程序包含:单链表的建立,测长,打印,删除节点,插入节点以及逆置
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define ok 1 6 #define error 0 7 8 typedef struct Node 9 { 10 int data; 11 struct Node *next; 12 }Node; 13 typedef struct Node *LinkList; 14 15 //建立链表 16 void CreatListTail(LinkList *L,int n) 17 { 18 LinkList p,r;//不加星号 19 int i=0,x; 20 *L=(LinkList)malloc(sizeof(Node)); 21 r=*L;//r是L的尾节点 22 printf("input %d numbers(1~99) to creat a linklist\n",n); 23 while(i<n) 24 { 25 scanf("%d",&x); 26 if(x>1&&x<99) 27 { 28 p=(LinkList)malloc(sizeof(LinkList));//循环中每个节点都应该新生成 29 p->data=x; 30 r->next=p; 31 r=p; 32 i++; 33 } 34 else 35 { 36 printf("illega number ,please input a number between 1 and 99.\n"); 37 fflush(stdin);//清空键盘输入流缓冲区,防止死循环(当输入字母时会进入死循环),不完美,仅对第一位输入字母有效 38 } 39 } 40 printf("OK\n"); 41 r->next=NULL; 42 } 43 44 //显示链表 45 void ListTraverse(LinkList L) 46 { 47 int i=0; 48 LinkList p=L->next;//指向第一个节点 49 while(p) 50 { 51 printf("%d ",p->data); 52 p=p->next; 53 i++; 54 } 55 printf("\n Linklist contain %d Nodes",i); 56 } 57 58 //删除链表元素 59 int ListDelete(LinkList L,int j,int *e) 60 { 61 LinkList p=L,q; 62 int i=1; 63 while(p->next && i<j) 64 { 65 p = p->next; 66 i++; 67 } 68 if(!(p->next)||i>j) 69 return error; 70 q=p->next; 71 p->next=q->next; 72 *e = q->data; 73 free(q); 74 q=NULL;//free之后,内存释放,但指针仍指向内存位置 75 printf("字符串变更为: \n"); 76 ListTraverse(L); 77 return ok; 78 } 79 80 //将节点插入链表 81 int ListInsert(LinkList L,int i, int e) 82 { 83 int j=1; 84 LinkList p,s; 85 p=L;//注意循环次数 86 while(p && j<i) 87 { 88 p=p->next; 89 j++; 90 } 91 if(!p || j>i) 92 return error; 93 s=(LinkList)malloc(sizeof(Node)); 94 s->data=e; 95 s->next=p->next; 96 p->next=s; 97 return ok; 98 } 99 100 //逆序链表(使用递归) 待修改总是报错 101 LinkList *ListRever(LinkList *L) 102 { 103 LinkList p,Node,Next,HeadNode; 104 p=*L;//头结点 105 if(p==NULL) 106 return NULL;//链表操作要有安全检查,头结点不为空 107 if(p->next==NULL) 108 return p;//递归的结束点,即为逆序后的头结点,函数的返回值HeadNode 109 Node = p; 110 Next = p->next; 111 HeadNode = ListRever(Next); 112 Next->next = Node;//逆置 113 Node->next = NULL;//防止产生循环列表 114 return HeadNode; 115 } 116 //1.用递归算法,对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1) 117 //考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:a2->next=a1;a1->next=NULL;return a2; 118 //a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2' 119 //from(http://blog.sina.com.cn/s/blog_4d7c6fd50100y0ql.html) 120 121 122 int main() 123 { 124 int n=1,e,j; 125 LinkList L; 126 printf("input n \n"); 127 scanf("%d",&n); 128 CreatListTail(&L, n);//采用&L:函数中是引用型的,这里将地址传递 129 ListTraverse(L);//显示字符串和长度 130 131 printf("\n 删除第?个元素 \n"); 132 scanf("%d",&j); 133 ListDelete(L,j,&e);//删除第i个元素,并显示剩余链表 134 135 printf("\n 在第3个位置前插入e=3 \n"); 136 ListInsert(L,3,3); 137 ListTraverse(L); 138 139 ListRever(&L); 140 printf("逆置后 \n"); 141 ListTraverse(L); 142 143 144 145 }