[数据结构与算法] : 单向链表
Posted moon1992
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数据结构与算法] : 单向链表相关的知识,希望对你有一定的参考价值。
头文件
1 // filename: list.h 2 typedef int ElementType; 3 4 #ifndef _LIST_H_ 5 #define _LIST_H_ 6 7 struct Node; 8 typedef struct Node *PtrToNode; 9 typedef PtrToNode List; 10 typedef PtrToNode Position; 11 12 List MakeEmpty(List L); 13 int IsEmpty(List L); 14 int IsLast(Position P, List L); 15 Position Find(ElementType X, List L); 16 void Delete(ElementType X, List L); 17 Position FindPrevious(ElementType X, List L); 18 void Insert(ElementType X, List L, Position P); 19 void DeleteList(List L); 20 Position Header(List L); 21 Position First(List L); 22 Position Advance(Position P); 23 ElementType Retrieve(Position P); 24 void PrintElement(ElementType X); 25 void TraversList(List L); // 正序遍历(递归法) 26 void ReverseTraversList(List L); // 逆序遍历(递归法) 27 void TraverseL(List L); // 对于一个庞大的栈递归可能造成越出栈空间, 使用goto消除尾递归 28 void TraverseL2(List L); // while循环遍历 29 30 #endif
源文件
filename: list.c
1 #include "list.h" 2 #include <malloc.h> 3 #include <stdlib.h> 4 5 struct Node 6 { 7 ElementType Element; 8 PtrToNode Next; 9 }; 10 11 // 创建或者清空链表 12 List MakeEmpty(List L) 13 { 14 if(L != NULL) 15 DeleteList(L); 16 else 17 { 18 L = (List)malloc( sizeof(struct Node) ); 19 if(L == NULL) 20 { 21 exit(-1); 22 } 23 L->Next = NULL; // 非常重要 24 } 25 return L; 26 } 27 28 int IsEmpty(List L) 29 { 30 return L->Next == NULL; 31 } 32 33 int IsLast(Position P, List L) 34 { 35 return P->Next == NULL; 36 } 37 38 // 查找 39 Position Find(ElementType X, List L) 40 { 41 Position P; 42 P = L->Next; 43 while(P != NULL && P->Element != X) 44 P = P->Next; 45 return P; 46 } 47 48 // 删除, 注意先判断待删除的元素是否在链表中 49 void Delete(ElementType X, List L) 50 { 51 Position P = FindPrevious(X, L);// 获得待删除元素的前驱 52 53 if( !IsLast(P, L) ) // 如果X的前驱P是最后一个元素, 则表示L中无X 54 { 55 Position Q = P->Next; 56 P->Next = Q->Next; 57 free(Q); 58 } 59 } 60 61 // 查找前驱, 注意区分Find操作与FindPrevious的区别是P的初始值不同 62 Position FindPrevious(ElementType X, List L) 63 { 64 Position P; 65 P = L; 66 while(P->Next != NULL && P->Next->Element != X) 67 P = P->Next; 68 return P; 69 } 70 71 // 插入, 在P之后插入 72 void Insert(ElementType X, List L, Position P) 73 { 74 Position TmpCell; 75 // 先创建一个新节点 76 TmpCell = (List)malloc( sizeof(struct Node) ); 77 if(TmpCell == NULL) 78 { 79 exit(-1); 80 } 81 82 TmpCell->Element = X; 83 TmpCell->Next = P->Next; 84 P->Next = TmpCell; 85 } 86 87 // 销毁链表, 需要两个指针 88 void DeleteList(List L) 89 { 90 Position P, Q; 91 92 P = L->Next; // 重要, 保留头节点 93 L->Next = NULL; 94 while(P != NULL) 95 { 96 Q = P->Next; 97 free(Q); 98 P = Q; 99 } 100 } 101 102 Position Header(List L) 103 { 104 return L; 105 } 106 107 Position First(List L) 108 { 109 return L->Next; 110 } 111 112 Position Advance(Position P) 113 { 114 return P->Next; 115 } 116 117 ElementType Retrieve(Position P) 118 { 119 return P->Element; 120 } 121 122 void PrintElement(ElementType X) 123 { 124 printf("%d ", X); 125 } 126 127 // 递归遍历链表 128 void TraversList(List L) 129 { 130 if(L != NULL) 131 { 132 PrintElement(L->Element); 133 TraversList(L->Next); 134 } 135 } 136 137 // 递归反向打印链表 138 void ReverseTraversList(List L) 139 { 140 if(L != NULL) 141 { 142 ReverseTraversList(L->Next); 143 PrintElement(L->Element); 144 } 145 } 146 147 void TraverseL(List L) 148 { 149 top: 150 if(L != NULL) 151 { 152 PrintElement(L->Element); 153 L = L->Next; 154 goto top; 155 } 156 } 157 158 // 遍历链表, 非递归实现, 推荐 159 void TraverseL2(List L) 160 { 161 while(L != NULL) 162 { 163 PrintElement(L->Element); 164 L = L->Next; 165 } 166 }
测试文件
1 #include "list.h" 2 #include <stdio.h> 3 4 void 5 PrintList( const List L ) 6 { 7 Position P = Header( L ); 8 9 if( IsEmpty( L ) ) 10 printf( "Empty list\n" ); 11 else 12 { 13 do 14 { 15 P = Advance( P ); 16 printf( "%d ", Retrieve( P ) ); 17 } while( !IsLast( P, L ) ); 18 printf( "\n" ); 19 } 20 } 21 22 void TraverseList(const List L) 23 { 24 Position P = Header(L); 25 if( IsEmpty(L) ) 26 printf("链表为空\n"); 27 else 28 { 29 do 30 { 31 P = Advance(P); 32 printf("%d ", Retrieve(P)); 33 } while( !IsLast(P, L) ); 34 printf("\n"); 35 } 36 } 37 38 main( ) 39 { 40 List L; 41 Position P; 42 int i; 43 44 L = MakeEmpty( NULL ); 45 P = Header( L ); 46 // TraverseList( L ); 47 TraverseList(L); 48 49 for( i = 0; i < 10; i++ ) 50 { 51 Insert( i, L, P ); 52 TraverseList( L ); 53 P = Advance( P ); 54 } 55 for( i = 0; i < 10; i+= 2 ) 56 Delete( i, L ); 57 58 for( i = 0; i < 10; i++ ) 59 if( ( i % 2 == 0 ) == ( Find( i, L ) != NULL ) ) 60 printf( "Find fails\n" ); 61 62 printf( "Finished deletions\n" ); 63 64 TraverseList( L ); 65 TraversList( Advance(L) ); 66 printf("\n"); 67 ReverseTraversList( Advance(L) ); 68 printf("\n"); 69 TraverseL( Advance(L) ); 70 printf("\n"); 71 TraverseL2( Advance(L) ); 72 printf("\n"); 73 74 DeleteList( L ); 75 76 return 0; 77 }
以上是关于[数据结构与算法] : 单向链表的主要内容,如果未能解决你的问题,请参考以下文章