無頭單鏈表
阿新 • • 發佈:2018-11-10
一、連結串列概念
1、連結串列:一種鏈式儲存的線性表,用一組地址任意的儲存單元存放線性表的資料元素,稱儲存單元為一個節點
2、連結串列有單鏈表、雙鏈表和雙向迴圈連結串列,每種連結串列都有無頭和帶頭兩種,帶頭就是頭結點不存放資料元素
二、原始碼
1、linklist.h
#ifndef __LINKLIST_H__ #define __LINKLIST_H__ #include "stdio.h" #include "assert.h" #include "string.h" #include "malloc.h" #include "stdlib.h" typedef int DataType; typedef struct Node { DataType data; struct Node* next; }List, *pList; void InitLinkList(pList* pplist); pList BuyNode(DataType d); void DestroyLinkList(pList* pplist); void PushBack(pList* pplist, DataType d); void PopBack(pList* pplist); void PushFront(pList* pplist, DataType d); void PopFront(pList* pplist); pList Find(pList plist, DataType d); void Insert(pList* pplist, pList pos, DataType d); void Erase(pList* pplist, pList pos); void Remove(pList* pplist, DataType d); void RemoveAll(pList* pplist, DataType d); void PrintLinkList(pList plist); int GetListLength(pList plist); void PrintTailToHead(pList plist); #endif
2、linklist.c
#include "linklist.h" //初始化 void InitLinkList(pList* pplist) { assert(pplist); *pplist = NULL; } //建立結點 pList BuyNode(DataType d) { pList node = (pList)malloc(sizeof(List)); node->data = d; node->next = NULL; return node; } //清除連結串列 void DestroyLinkList(pList* pplist) { assert(pplist); while ((*pplist)!=NULL) { PopBack(pplist); } } //尾插 void PushBack(pList* pplist, DataType d) { if (*pplist == NULL) *pplist = BuyNode(d); else { pList p = *pplist; while (p->next) { p = p->next; } p->next = BuyNode(d); } } //尾刪 void PopBack(pList* pplist) { assert(pplist); if (*pplist == NULL) return; if ((*pplist)->next == NULL) { free(*pplist); *pplist = NULL; } else { pList tmp = *pplist; while (tmp->next->next) { tmp = tmp->next; } free(tmp->next); tmp->next = NULL; } } //頭插 void PushFront(pList* pplist, DataType d) { assert(pplist); pList p = BuyNode(d); p->next = *pplist; *pplist = p; } //頭刪 void PopFront(pList* pplist) { assert(pplist); pList p; if (*pplist == NULL) return; else { p = (*pplist)->next; free(*pplist); *pplist = p; } } //找出指定元素 pList Find(pList plist, DataType d) { assert(plist); while (plist) { if (plist->data == d) return plist; else plist = plist->next; } return NULL; } //在指定位置之前插入一個值 void Insert(pList* pplist, pList pos, DataType d) { assert(pplist); pList tmp = *pplist; while (tmp->next->data != pos->data) { tmp = tmp->next; } pos = tmp->next; tmp->next = BuyNode(d); tmp->next->next = pos; } //指定位置刪除 void Erase(pList* pplist, pList pos) { assert(pplist); pList tmp = *pplist; if (tmp == NULL) return; if (tmp->next == NULL) { PopBack(pplist); return; } while (tmp->next != pos) { tmp = tmp->next; } pos = tmp->next->next; free(tmp->next); tmp->next = pos; } //刪除指定元素 void Remove(pList* pplist, DataType d) { assert(pplist); pList tmp = *pplist; if (tmp == NULL) return; if (tmp->next == NULL) { PopBack(pplist); return; } while (tmp->next->data != d) { tmp = tmp->next; } pList cur = tmp->next->next; free(tmp->next); tmp->next = cur; } //刪除所有的指定元素 void RemoveAll(pList* pplist, DataType d) { assert(pplist); pList tmp = *pplist; while (tmp->next) { if (tmp->data == d) { pList p = tmp->next; free(tmp); tmp = p; } else { if (tmp->next->data == d) { pList cur = tmp->next->next; free(tmp->next); tmp->next = cur; } else tmp = tmp->next; } } } //列印 void PrintLinkList(pList plist) { assert(plist); while (plist) { printf("%d ", plist->data); plist=plist->next; } printf("\n"); } //連結串列長 int GetListLength(pList plist) { assert(plist); int count = 1; while (plist->next != NULL) { plist = plist->next; count++; } return count; } //逆序列印單項鍊表 void PrintTailToHead(pList plist) { assert(plist); pList tmp = NULL; while (plist->next != tmp) { pList cur = plist; while (cur->next->next != tmp) { cur = cur->next; } printf("%d ", cur->next->data); tmp = cur->next; } printf("%d\n", plist->data); }