1. 程式人生 > >考研資料結構複習之線性表(二)

考研資料結構複習之線性表(二)

單鏈表的學習

#pragma once
typedef char DataType;
class SSeqListTest
{
public:
    SSeqListTest();
    ~SSeqListTest();
};
typedef struct Node {
    DataType data;
    struct  Node *next;
}ListNode,*LinkList;

void InitLinkList(LinkList *head);
bool IsLinkListEmpty(LinkList head);
ListNode *Get(LinkList
head,int i)
; ListNode *LocateElem(LinkList head,DataType e); int LocatePosition(LinkList head,DataType e); int InsertList(LinkList head,int i,DataType e); int DeleteList(LinkList head,int i,DataType *e); int ListLength(LinkList head); void DestroyList(LinkList head);

完整的實現程式碼如下:

#include "SSeqListTest.h"
#include<malloc.h> #include<iostream> using namespace std; SSeqListTest::SSeqListTest() { } SSeqListTest::~SSeqListTest() { } /*這裡初始化的函式為void InitLinkList(LinkList * head); 它的引數為LinkList * head,媽啊,相當於int **P, 你需要理解透徹,不理解透徹的話也可以參考之前的線性表的初始化: 線性表的初始化: void InitList(SeqList * L) { L->length
= 0; } 所以可以完全照搬。 但是在考研的資料結構中製作節點有兩種方式: 拿簡單的順序表舉例子: (1)直接製作:SeqList L (2)間接製作:SeqList *L; L=(SeqList *)malloc(sizeof(SeqList)); 考研中第二種考查的比較多。 void InitLinkList(ListNode *head) { if ((head=(LinkList)malloc(sizeof(ListNode)))==NULL) { exit(-1); } (head)->next = NULL; cout << "分配成功" << endl; }*/ //但是實際上使用最多的初始化方式是下面這種,以後樹的章節你還會見到。 void InitLinkList(LinkList *head) { if ((*head=(LinkList)malloc(sizeof(ListNode)))==NULL) { exit(-1); } (*head)->next = NULL; cout << "分配成功" << endl; } bool IsLinkListEmpty(LinkList head) { if (head->next==NULL) { return true; } return false; } /*按照序號來查詢元素操作*/ //這裡需要注意的是返回的是i個位置的指標返回型別應該寫成ListNode *、 //大家也都知道ListNode *L=LinkList L; //所以自然也可以這樣寫:LinkList Get(LinkList head, int i) //兩者的效果是一樣的,親自動手一下就知道了。 //以下的函式返回時指標型別的同樣的解釋。 ListNode * Get(LinkList head, int i) { ListNode *p; int j=0; if (IsLinkListEmpty(head)) { return NULL; } else if(i<1){ return NULL; } else { p = head; while (p->next!=NULL&&j<i) { p = p->next; j++; } if (j==i) { return p; } else { return NULL; } } } /*查找節點值為e的節點並返回所對應的指標*/ ListNode *LocateElem(LinkList head, DataType e) { ListNode *p; p = head->next; while (p) { if (p->data!=e) { p = p->next; } else { break; } } return p; } //通過元素值定位位置,缺點在於如果有兩個位置的資料值一樣,只能定位到前一個位置。 int LocatePosition(LinkList head, DataType e) { ListNode *p; int i = 1; if (IsLinkListEmpty(head)) { return -1; } p = head->next; while (p!=NULL) { if (p->data==e) { return i; } else { p = p->next; i++; } } if (p==NULL) { return -1; } else { return 1; } } /*在i的位置插入元素,需要找到之前的i-1的指標*/ int InsertList(LinkList head, int i, DataType e) { ListNode *pre, *p; pre = head; int j = 0; /*找到i-1個節點*/ while (pre->next!=NULL&&j<i-1) { pre = pre->next; j++; } if (j!=i-1) { cout << "插入的節點位置有錯" << endl; return -1; } if ((p=(ListNode*)malloc(sizeof(ListNode)))==NULL) { exit(-1); } p->data = e; p->next = pre->next; pre->next = p; return 1; } //根據位置刪除掉單鏈表中的元素。 int DeleteList(LinkList head, int i, DataType * e) { ListNode *pre, *p; int j = 0; pre = head; while (pre->next != NULL&&pre->next->next!=NULL&&j<i-1) { pre = pre->next; j++; } if (j!=i-1) { cout << "刪除位置出錯" << endl; return -1; } p = pre->next; *e = p->data; pre->next = p->next; /*釋放P節點指向的點*/ free(p); return 1; } //得到單鏈表的長度。 int ListLength(LinkList head) { LinkList p; p = head; int count = 0; while (p->next!=NULL) { p = p->next; count++; } return count; } //銷燬單聊表 void DestroyList(LinkList head) { ListNode *p,*q; p = head; while (p!=NULL) { q = p; p = p->next; free(q); } }

測試函式:

int main(){
    cout << "測試開始"<<endl;
    LinkList L;
    InitLinkList(&L);
    InsertList(L,1,'a');
    cout << "單鏈表長度" << ListLength(L)<<endl;
    LinkList getElumByNum;
    getElumByNum = Get(L, 1);
    cout <<"第一個位置元素是:"<< getElumByNum->data << endl;
    DataType deleteElumValue;
    DeleteList(L,1,&deleteElumValue);
    cout << deleteElumValue << endl;
    cout << "單鏈表長度" << ListLength(L) << endl;
    system("PAUSE");
    return 0;
}

執行結果:
這裡寫圖片描述