資料結構——線性表的鏈式實現
阿新 • • 發佈:2018-11-04
記錄一下比較完整的鏈式線性表的函式操作集
語言C++ 環境codeblocks17.01
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #define Status int #define ElemType int using namespace std; typedef struct LNode //struct link = Link { ElemType data; struct LNode *next; } LNode,*LinkList; Status InitList (LinkList &L) {/*初始化*/ L = new LNode; L->next = NULL; return 1; } Status ListInsert(LinkList &L, int i,ElemType e) {/*連結串列插入元素e*/ LNode *p = L; int j=0; while(p && (j<i-1)) { p = p->next; j++; } if(!p||j>i-1) return -1; LNode *s; s = new LNode; s->data = e; s->next = p->next; // s->next = NULL; or s->next = p->next p->next = s; return 1; } Status ListTraverse(LinkList &L) {/*連結串列遍歷輸出*/ LNode *p = L; p = p->next; while(p) { printf("%d ",p->data); p = p->next; } return 1; } Status ListReverse(LinkList &L) {/*連結串列逆序*/ if(L==NULL||L->next==NULL) return -1; LNode* pNext = L->next->next; LNode* pNode = L->next; LNode* pTemp = L->next->next->next; LNode* pFirst = L->next; // 記錄原連結串列的第一個節點,即逆轉後的tail node // 每次處理兩個節點 while(pNode->next && pNext) { pNext->next = pNode; // 迭代逆轉的兩個節點是 pnext pnode pNode = pNext; pNext = pTemp; if(pTemp!=NULL) pTemp = pTemp->next; else ; } L->next = pNode; // 頭節點指向新的第一個元素節點 pFirst->next = NULL; // tail node = NULL return 1; } Status ListSort_1(LinkList &L) {/*使用sort函式時間複雜為(O(nlogn))*/ int i=0; LNode* h = L; if(h->next==NULL||h==NULL) return -1; ElemType* temp = new ElemType[100]; //變數連結串列存放在陣列中 for(i=0, h=h->next; h; h=h->next,i++) { temp[i] = h->data; } sort(temp, temp+i); h = L; // 資料複製回到list for(i=0, h=h->next; h; h=h->next,i++) { h->data = temp[i]; } return 1; } Status ListSort_2(LinkList &L) {/*線性表的排序,採用氣泡排序,直接遍歷連結串列*/ LNode* h = L; //作為一個臨時量 LNode* p; LNode* p1; //如果連結串列為空直接返回 if (h->next==NULL||h==NULL) return-1; for (p = L; p->next!=NULL ; p = p->next) { for (p1 = p; p1->next!=NULL ; p1 = p1->next) { //如果前面的那個比後面的那個大,就交換它們之間的是資料域 if (p1->data > p1->next->data) { ElemType temp = p->data; p->data = p1->next->data; p1->next->data = temp; } } } return 1; } Status ListDeleteEvenNum(LinkList &L) {/*刪除所有偶數元素節點*/ if (L->next==NULL||L==NULL) return-1; LNode* p = L; LNode* pre; // 前驅結點 pre = p; p = p->next; while(p) { if(p->data%2 == 0) { pre->next = p->next; free(p); p = pre->next; continue; } p = p->next; pre = pre->next; } return 1; } Status MergeList(LinkList &L1,LinkList &L2) {/*連結兩個連結串列*/ if((L1->next==NULL||L1==NULL)&&(L2->next==NULL||L2==NULL)) //兩個都是空連結串列 return -1; LNode* p1; p1 = L1->next; while(p1->next) { p1 = p1->next; } p1->next = L2->next; // 連結L1和L2 return 1; } Status ListSplitEvenOdd(LinkList &L1, LinkList &L2) {/*按照奇偶拆分L1 結果是L1存放奇數 L2存放偶數*/ if (L1->next==NULL||L1==NULL) return-1; InitList(L2); int i=1; LNode* p = L1; LNode *pre; pre = p; p = L1->next; while(p) { if(p->data%2 == 0) { // 將L1中的偶數節點插入到L2中 pre->next = p->next; ListInsert(L2,i,p->data); i++; free(p); p = pre->next; continue; } p = p->next; pre = pre->next; } return 1; } Status DestroyList(LinkList &L) {/*銷燬連結串列*/ if(L==NULL) return -1; LNode* p; // 從L的頭節點開始刪除 while(L) { p = L; L = L->next; free(p); } return 1; // L的頭節點已經不在了 } Status ClearList(LinkList &L) {/*清空連結串列*/ if(L==NULL) return -1; LNode* p,* l; // 從L的首元節開始刪除 l = L->next; while(l) { p = l; l = l->next; delete p; } L->next = NULL; //?????????????????????????????????????? return 1; // L的頭節點還在 } Status ListEmpty(LinkList &L) {/*判斷連結串列為空返回1 否則返回0*/ if(L==NULL) return -1; else { if(L->next==NULL) // 判斷連結串列是否為空 return 1; else return 0; } } Status GetElem(LinkList &L,int i ,ElemType &e) {/*取得L中第i個元素*/ LNode *p = L->next; int j=1; while(p && j<i) { p = p->next; j++; } if(!p || j<i || i<1) // 如果p為空或者目標元素不在範圍內,返回錯誤-1 return -1; e = p->data; return 1; } Status GetElemNode(LinkList &L , ElemType e, LNode* &pe) {/*取得L中第1個等於e的元素的指標 , 取得返回 1,未找到返回 0*/ if(L==NULL) return -1; LNode* p = L->next; while(p) { if(p->data == e) { pe = p; return 1; } p = p->next; } return 0; } int ListLenght(LinkList &L) {/*返回連結串列長度*/ if(L==NULL) return -1; LNode* p = L; int len = 0; p = p->next; while (p) { p = p->next; len++; } return len; } int compare(ElemType a , ElemType b) {/*判斷ab的關係,返回一個int來表示ab關係*/ /* -1 a<b 1 a>b 0 a=b */ if(a==b) return 0; else if (a>b) return 1; else return -1; } int LocateElem(LinkList &L ,ElemType e,int compare(ElemType , ElemType), int mod) {/*通過compare()函式 判定e和L中第一個符合mod(compare中ab的關係判定返回值0,1,-1)的元素的位置*/ if(L==NULL) return -1; LNode* p = L->next; int location=1; while(p) { if(compare(e,p->data)==mod) // 當e與L中的元素符合mod關係時返回其位置 return location; p = p->next; location++; } return 0; } Status NextElem(LinkList &L, ElemType cur_e, LinkList & next_e) { /*用next_e返回cur_e的前驅結點 ,cur_e的位置不能在尾元 否則返回0*/ if(L==NULL) return -1; int j = 1; LNode* p = L->next; while(p) { if(p->data == cur_e) {p = p->next; break;} p = p->next; j++; } if(p==NULL) // 在尾元 return 0; next_e = p; return 1; } Status PriorElem(LinkList &L, ElemType cur_e, LinkList & pre_e) {/*用pre_e返回L中第一個值為cur_e的元素的前驅結點 ,cur_e的位置不能在首元*/ if(L == NULL) return -1; int j = 1; LNode* P = L->next; while(p) { if(p->data == cur_e) break; p = p->next; j++; } if(j<2) // 在首元 返回-1 return -1; else if(p==NULL) // 未找到 返回0 return 0; else { pre_e = p; // 找到 return 1; } } Status DeleteElem_value(LinkList &L,ElemType e) {/*刪除L中值為e的所有節點,成功返回1 失敗返回0*/ if(L==NULL) return 0; LNode* p = L->next; LNode* pre = L; while(p) { if(p->data==e) { pre->next = p->next; // 連結要刪除的節點的前後節點 free(p); // 釋放節點 break; } pre = p; p = p->next; } if(p==NULL) return 0; else return 1; } Status DeleteAllElem_value(LinkList &L,ElemType e) {/*刪除L中值為e的所有節點,成功返回1 失敗返回0*/ if(L==NULL) return 0; LNode* p = L->next; LNode* pre = L; while(p) { if(p->data==e) { pre->next = p->next; // 連結要刪除的節點的前後節點 free(p); // 釋放節點 p = pre->next; continue; } pre = p; p = p->next; } return 1; } Status DeleteElem_location(LinkList &L,int location) {/*刪除L中第location位置的節點,成功返回1 失敗返回0*/ if(L==NULL) return 0; LNode* p = L->next; LNode* pre = L; int j = 1; while(p) { if(j==location) { pre->next = p->next; // 連結要刪除的節點的前後節點 free(p); // 釋放節點 break; } j++; pre = p; p = p->next; } if(p==NULL) return 0; else return 1; } int main() { /*main 測試函式*/ LNode *L; int temp; int i = 1; InitList(L); while(1) { scanf("%d",&temp); if(temp==0) break; ListInsert(L,i,temp); i++; } ListTraverse(L); return 0; }