動態鏈表的定義
//定義一個動態鏈表 typedef int ElemType; typedef struct LNode { ElemType data; struct LNode* next; }LNode, *LinkList;
創建一個動態鏈表
//創建一個動態鏈表 void CreateList(LinkList* L, int len) { printf("請輸入 %d 個數據:", len); //創建鏈表的頭節點 *L = (LinkList)malloc(sizeof(LNode)); //定義一個指向尾節點的指針和一個指向創建結點的指針 LinkList rear = *L, p = NULL; //創建指定大小的空間 for (int i = 1; i < len + 1; ++i) { p = (LinkList)malloc(sizeof(LNode)); scanf("%d", &p->data); //尾指針連接新結點 rear->next = p; //改變尾指針位置 rear = p; } //尾指針之後爲空 rear->next = NULL; } //逆序 //void CreateList(LinkList* L, int len) { // printf("請輸入 %d 個數據:", len); // //創建頭節點 // *L = (LinkList)malloc(sizeof(LNode)); // (*L)->next = NULL; // //定義一個指向創建結點的指針 // LinkList p = NULL; // for (int i = 1; i < len; ++i) { // p = (LinkList)malloc(sizeof(LNode)); // scanf("%d", &p->data); // p->next = (*L)->next; // (*L)->next = p; // } // printf("\n"); //}
求鏈表的長度
//鏈表長度 int Length(LinkList L) { int len = 0; while (L->next != NULL) { ++len; L = L->next; } return len; }
向動態鏈表中插入結點
//向動態鏈表中插入結點 void InsertList(LinkList* L, int pos, ElemType e) { //判斷插入位置是否合理 if (pos < 1 || pos > Length(*L) + 1) { printf("插入位置不合理\n"); return;// exit(0); } LinkList adjust = *L; LinkList insert = (LinkList)malloc(sizeof(LNode)); insert->data = e; //調整adjust的位置, 準備連接 int i = 0; while (i++ < pos - 1) { adjust = adjust->next; } //連接右端 insert->next = adjust->next; //連接左端 adjust->next = insert; }
從動態鏈表中刪除結點
//從動態鏈表中刪除結點 void DeleteList(LinkList* L, int pos) { //判斷刪除結點的位置是否合理 if (pos < 1 || pos > Length(*L)) { printf("刪除結點的位置不合理\n"); return;// exit(0); } LinkList adjust = *L; //調整刪除位置, 準備刪除指定結點 int i = 0; while (i++ < pos - 1) { adjust = adjust->next; } //保存要刪除的結點 LinkList deleted = adjust->next; //連接要刪除結點的兩端結點 adjust->next = deleted->next; //釋放結點 free(deleted); }
銷燬一個動態鏈表
//銷燬一個動態鏈表 void DestroyList(LinkList* L) { LinkList adjust = *L; while (*L) { //調整指針始終在頭節點的下一個位置, 用來保存新的頭節點 adjust = (*L)->next; //釋放頭節點 free(*L); //調整新頭節點的位置 *L = adjust; } printf("鏈表已銷燬\n"); }
清空一個動態鏈表
//清空一個動態鏈表 void ClearList(LinkList* L) { LinkList adjust = (*L)->next; while ((*L)->next) { //調整指針始終指向被刪除結點的下一個結點, 用來保存下一個要被刪除的結點 adjust = adjust->next; //每次釋放頭節點的下一個結點 free((*L)->next); //更新頭節點的下一個結點(調整指針指向的結點) (*L)->next = adjust; } printf("鏈表已清空\n"); }
判斷鏈表是否爲空
//判斷鏈表是否爲空 int IsEmpty(LinkList L) { if (L->next == NULL) { //printf("鏈表爲空\n"); return 1; } //printf("鏈表不爲空\n"); return 0; }
獲取動態鏈表上的某個值
//獲取動態鏈表上某個位置上的值 ElemType GetElem(LinkList L, int pos) { //判斷獲取位置是否合理 if (pos < 1 || pos > Length(L)) { printf("獲取位置不合理\n"); return 0;// exit(0); } LinkList adjust = L; //調整獲取位置 int i = 0; while (i++ < pos) { adjust = adjust->next; } //返回獲取值 return adjust->data; }
在動態鏈表中查找某個元素
//在動態鏈表中查找某個元素 void LocateElem(LinkList L, ElemType e) { LinkList adjust = L->next; int count = 0; //遍歷鏈表 while (adjust) { ++count; if (adjust->data == e) { printf("找到了該元素, 它是第 %d 個元素\n", count); return; } adjust = adjust->next; } printf("沒有找到該元素\n"); }
在動態鏈表中查找某個元素的前驅
//在動態鏈表中查找某個元素的前驅 ElemType ProriElem(LinkList L, ElemType cur_e) { //判斷是否爲第一個元素 if (L->next->data == cur_e) { printf("第一個元素無前驅\n"); return 0; } //從第二個元素開始查找 LinkList adjust = L->next; while (adjust->next) { if (adjust->next->data == cur_e) { return adjust->data; } adjust = adjust->next; } printf("沒有該元素\n"); return 0; }
在動態鏈表中查找某個元素的後繼
//在動態鏈表中找某個元素的後繼 ElemType NextElem(LinkList L, ElemType cur_e) { //從第一個元素查找, 最後一個元素要進行判斷 LinkList adjust = L->next; while (adjust) { if (adjust->data == cur_e) { if (adjust->next != NULL) { return adjust->next->data; } printf("最後一個元素沒有後繼\n"); return 0; } adjust = adjust->next; } printf("沒有該元素\n"); return 0; }
遍歷鏈表
//遍歷鏈表 void Traverse(LinkList L) { //判斷鏈表是否爲空 if (L->next == NULL) { printf("鏈表爲空\n"); return; } while (L->next != NULL) { printf("%d ", L->next->data); L = L->next; } printf("\n"); }
測試
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> //定義一個動態鏈表 typedef int ElemType; typedef struct LNode { ElemType data; struct LNode* next; }LNode, *LinkList; //創建一個動態鏈表 void CreateList(LinkList* L, int len) { printf("請輸入 %d 個數據:", len); //創建鏈表的頭節點 *L = (LinkList)malloc(sizeof(LNode)); //定義一個指向尾節點的指針和一個指向創建結點的指針 LinkList rear = *L, p = NULL; //創建指定大小的空間 for (int i = 1; i < len + 1; ++i) { p = (LinkList)malloc(sizeof(LNode)); scanf("%d", &p->data); //尾指針連接新結點 rear->next = p; //改變尾指針位置 rear = p; } //尾指針之後爲空 rear->next = NULL; } //逆序 //void CreateList(LinkList* L, int len) { // printf("請輸入 %d 個數據:", len); // //創建頭節點 // *L = (LinkList)malloc(sizeof(LNode)); // (*L)->next = NULL; // //定義一個指向創建結點的指針 // LinkList p = NULL; // for (int i = 1; i < len; ++i) { // p = (LinkList)malloc(sizeof(LNode)); // scanf("%d", &p->data); // p->next = (*L)->next; // (*L)->next = p; // } // printf("\n"); //} //鏈表長度 int Length(LinkList L) { int len = 0; while (L->next != NULL) { ++len; L = L->next; } return len; } //向動態鏈表中插入結點 void InsertList(LinkList* L, int pos, ElemType e) { //判斷插入位置是否合理 if (pos < 1 || pos > Length(*L) + 1) { printf("插入位置不合理\n"); return;// exit(0); } LinkList adjust = *L; LinkList insert = (LinkList)malloc(sizeof(LNode)); insert->data = e; //調整adjust的位置, 準備連接 int i = 0; while (i++ < pos - 1) { adjust = adjust->next; } //連接右端 insert->next = adjust->next; //連接左端 adjust->next = insert; } //從動態鏈表中刪除結點 void DeleteList(LinkList* L, int pos) { //判斷刪除結點的位置是否合理 if (pos < 1 || pos > Length(*L)) { printf("刪除結點的位置不合理\n"); return;// exit(0); } LinkList adjust = *L; //調整刪除位置, 準備刪除指定結點 int i = 0; while (i++ < pos - 1) { adjust = adjust->next; } //保存要刪除的結點 LinkList deleted = adjust->next; //連接要刪除結點的兩端結點 adjust->next = deleted->next; //釋放結點 free(deleted); } //銷燬一個動態鏈表 void DestroyList(LinkList* L) { LinkList adjust = *L; while (*L) { //調整指針始終在頭節點的下一個位置, 用來保存新的頭節點 adjust = (*L)->next; //釋放頭節點 free(*L); //調整新頭節點的位置 *L = adjust; } printf("鏈表已銷燬\n"); } //清空一個動態鏈表 void ClearList(LinkList* L) { LinkList adjust = (*L)->next; while ((*L)->next) { //調整指針始終指向被刪除結點的下一個結點, 用來保存下一個要被刪除的結點 adjust = adjust->next; //每次釋放頭節點的下一個結點 free((*L)->next); //更新頭節點的下一個結點(調整指針指向的結點) (*L)->next = adjust; } printf("鏈表已清空\n"); } //判斷鏈表是否爲空 int IsEmpty(LinkList L) { if (L->next == NULL) { //printf("鏈表爲空\n"); return 1; } //printf("鏈表不爲空\n"); return 0; } //獲取動態鏈表上某個位置上的值 ElemType GetElem(LinkList L, int pos) { //判斷獲取位置是否合理 if (pos < 1 || pos > Length(L)) { printf("獲取位置不合理\n"); return 0;// exit(0); } LinkList adjust = L; //調整獲取位置 int i = 0; while (i++ < pos) { adjust = adjust->next; } //返回獲取值 return adjust->data; } //在動態鏈表中查找某個元素 void LocateElem(LinkList L, ElemType e) { LinkList adjust = L->next; int count = 0; //遍歷鏈表 while (adjust) { ++count; if (adjust->data == e) { printf("找到了該元素, 它是第 %d 個元素\n", count); return; } adjust = adjust->next; } printf("沒有找到該元素\n"); } //在動態鏈表中查找某個元素的前驅 ElemType ProriElem(LinkList L, ElemType cur_e) { //判斷是否爲第一個元素 if (L->next->data == cur_e) { printf("第一個元素無前驅\n"); return 0; } //從第二個元素開始查找 LinkList adjust = L->next; while (adjust->next) { if (adjust->next->data == cur_e) { return adjust->data; } adjust = adjust->next; } printf("沒有該元素\n"); return 0; } //在動態鏈表中找某個元素的後繼 ElemType NextElem(LinkList L, ElemType cur_e) { //從第一個元素查找, 最後一個元素要進行判斷 LinkList adjust = L->next; while (adjust) { if (adjust->data == cur_e) { if (adjust->next != NULL) { return adjust->next->data; } printf("最後一個元素沒有後繼\n"); return 0; } adjust = adjust->next; } printf("沒有該元素\n"); return 0; } //遍歷鏈表 void Traverse(LinkList L) { //判斷鏈表是否爲空 if (L->next == NULL) { printf("鏈表爲空\n"); return; } while (L->next != NULL) { printf("%d ", L->next->data); L = L->next; } printf("\n"); } int main() { LinkList L1; CreateList(&L1, 5); Traverse(L1); InsertList(&L1, 4, 100); Traverse(L1); int value = GetElem(L1, 4); printf("%d\n", value); LocateElem(L1, 100); int prori_e = ProriElem(L1, 100); printf("%d\n", prori_e); int next_e = NextElem(L1, 100); printf("%d\n", next_e); DeleteList(&L1, 4); Traverse(L1); system("pause"); return 0; }
效果圖
希望能得到大家的指點和支持