大話資料結構,雙端迴圈連結串列,源程式
阿新 • • 發佈:2019-02-18
在網上找了下大話資料結構這本書的原始碼,發現第三章雖然有說到雙端連結串列卻沒給出實現,於是自己線上性連結串列的基礎上修改了一下,原始碼如下:
我將只有一個頭結點的時候,頭結點的next和prior都指向自己。
主要是注意一下插入的時候基本都遵循這個模型:,也就是找到要插入的地方的前一個數據的座標(可能是頭結點)。
#include "stdio.h" #include "string.h" #include "ctype.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 /* 儲存空間初始分配量 */ #define RANDOMINT(m,n) ((int)(rand()%(n-m+1)+m)) typedef int Status;/* Status是函式的型別,其值是函式結果狀態程式碼,如OK等 */ typedef int ElemType;/* ElemType型別根據實際情況而定,這裡假設為int */ Status visit(ElemType c) { printf("%d ", c); return OK; } typedef struct DulNode { ElemType data; struct DulNode *next; struct DulNode *prior; }DulNode; typedef struct DulNode *DuLinkList; /* 初始化順序線性表 */ Status InitList(DuLinkList *L) { if ((*L = (DuLinkList)malloc(sizeof(DulNode))) != NULL) { (*L)->next = (*L); (*L)->prior = (*L); return OK; } else return ERROR; } /* 初始條件:順序線性表L已存在。操作結果:若L為空表,則返回TRUE,否則返回FALSE */ Status ListEmpty(DuLinkList L) { if (L->next != L) return FALSE; else return TRUE; } /* 初始條件:順序線性表L已存在。操作結果:將L重置為空表 */ Status ClearList(DuLinkList *L) { DuLinkList p, q; q = (*L)->next; (*L)->next = *L; (*L)->prior = *L; while (q != *L) //首先判斷首元素是否空 { p = q->next; free(q); q = p; } return OK; } /* 初始條件:順序線性表L已存在。操作結果:返回L中資料元素個數 */ int ListLength(DuLinkList L) { int i = 0; DuLinkList p = L->next; /* p指向第一個結點 */ while (p != L) { p = p->next; ++i; } return i; } /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ /* 操作結果:用e返回L中第i個數據元素的值 */ Status GetElem(DuLinkList L, int i, ElemType *e) { if (i > ListLength(L) || i < 1 || ListLength(L) == 0) return ERROR; int j = 1; DuLinkList p; p = L->next; while (p!=L && j < i) { p = p->next; ++j; } *e = p->data; return OK; } /* 初始條件:順序線性表L已存在 */ /* 操作結果:返回L中第1個與e滿足關係的資料元素的位序。 */ /* 若這樣的資料元素不存在,則返回值為0 */ int LocateElem(DuLinkList L, ElemType e) { int i = 1; DuLinkList p = L->next; while (p!=L && p->data != e) { p = p->next; ++i; if (i > ListLength(L)) { return 0; } } return i; } /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L), */ /* 操作結果:在L中第i個位置之前插入新的資料元素e,L的長度加1 */ Status ListInsert(DuLinkList *L, int i, ElemType e) { if (i < 1) { return ERROR; } int j = 0; DuLinkList p, q, s; p = (*L); while (j < i - 1) //這裡判斷到達表末了不能寫在while迴圈裡面了 { p = p->next; j++; if (p == *L) break; } if (j < i - 1) { return ERROR; } s = (DuLinkList)malloc(sizeof(DulNode)); s->data = e; q = p->next; p->next = s; q->prior = s; s->prior = p; s->next = q; return OK; } /* 初始條件:順序線性表L已存在 */ /* 操作結果:依次對L的每個資料元素輸出 */ Status ListTraverse(DuLinkList L) { if (ListLength(L) < 1) return ERROR; DuLinkList p = L->next; while (p != L) { visit(p->data); p = p->next; } printf("\n"); return OK; } /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ /* 操作結果:刪除L的第i個數據元素,並用e返回其值,L的長度減1 */ Status ListDelete(DuLinkList *L, int i, ElemType *e) { if (i >= 1 && i <= ListLength(*L)) { DuLinkList p = (*L), q; int j = 0; while (j < i - 1) //找到第i-1個元素 { p = p->next; ++j; } q = p->next; *e = q->data; p->next = q->next; q->next->prior = p; free(q); return OK; } else return ERROR; } ///* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(頭插法) */ void CreateListHead(DuLinkList *L, int n) { DuLinkList p, q, s; int i = 0; srand(time(0)); /* 初始化隨機數種子 */ InitList(L); p = *L; for (i = 0; i != n; ++i) { s = (DuLinkList)malloc(sizeof(DulNode)); s->data = i; q = p->next; p->next = s; q->prior = s; s->prior = p; s->next = q; } } /* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(尾插法) */ void CreateListTail(DuLinkList *L, int n) { DuLinkList p, q; int i = 0; srand(time(0)); /* 初始化隨機數種子 */ InitList(L); p = *L; while (i < n) { i++; ListInsert(L, i, i); } } int main() { DuLinkList L; ElemType e; Status i; int j, k; i = InitList(&L); printf("初始化L後:ListLength(L)=%d\n", ListLength(L)); for (j = 1; j <= 5; j++) i = ListInsert(&L, 1, j); printf("在L的表頭依次插入1~5後:L.data="); ListTraverse(L); printf("ListLength(L)=%d \n", ListLength(L)); i = ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n", i); i = ClearList(&L); printf("清空L後:ListLength(L)=%d\n", ListLength(L)); i = ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n", i); for (j = 1; j <= 10; j++) ListInsert(&L, j, j); printf("在L的表尾依次插入1~10後:L.data="); ListTraverse(L); printf("ListLength(L)=%d \n", ListLength(L)); ListInsert(&L, 1, 0); printf("在L的表頭插入0後:L.data="); ListTraverse(L); printf("ListLength(L)=%d \n", ListLength(L)); GetElem(L, 5, &e); printf("第5個元素的值為:%d\n", e); for (j = 3; j <= 4; j++) { k = LocateElem(L, j); if (k) printf("第%d個元素的值為%d\n", k, j); else printf("沒有值為%d的元素\n", j); } k = ListLength(L); /* k為表長 */ for (j = k + 1; j >= k; j--) { i = ListDelete(&L, j, &e); /* 刪除第j個數據 */ if (i == ERROR) printf("刪除第%d個數據失敗\n", j); else printf("刪除第%d個的元素值為:%d\n", j, e); } printf("依次輸出L的元素:"); ListTraverse(L); j = 5; ListDelete(&L, j, &e); /* 刪除第5個數據 */ printf("刪除第%d個的元素值為:%d\n", j, e); printf("依次輸出L的元素:"); ListTraverse(L); i = ClearList(&L); printf("\n清空L後:ListLength(L)=%d\n", ListLength(L)); CreateListHead(&L, 20); printf("整體建立L的元素(頭插法):"); ListTraverse(L); i = ClearList(&L); printf("\n刪除L後:ListLength(L)=%d\n", ListLength(L)); CreateListTail(&L, 20); printf("整體建立L的元素(尾插法):"); ListTraverse(L); system("pause"); return 0; }