www.pudn.com > gc.rar > GC_8_1_LINKLIST.C
/*本程序精简,恨适合学习,包括了链表的各种算法*/ /*以后改进,增加插入任何位置的函数*/ /*以后改进,把所有关于链表的算法全部放置在其中*/ # include# include struct intNode { int value; struct intNode *next; }; struct intNode *head; /*能实现遍历链表功能的函数*/ void travelLink(struct intNode *h) { struct intNode *p = h; while (p!=NULL) { printf("%4d",p->value); /*输出表元的值*/ p=p->next; } printf("\n"); } /*无序链表上的动态查找*/ struct intNode *searchDSLink(struct intNode *h,int key,struct intNode **pp) { struct intNode *v = h, *u = NULL; while((v!=NULL) && (v->value !=key)) { u = v; /*准备考察下一个表元,当前表元成为后继表元的前驱表元*/ v = v->next; /*考察下一个表元,后继表元成为当前表元*/ } *pp = u; /* *pp是NULL时,找到的是首节点 ,当找到结点时,它是前驱结点*/ return v; /*返回NULL时,代表找不到,如果返回有值,那么*pp是它的前驱*/ } /*创建链表的函数*/ struct intNode *createList() { struct intNode *h, /*链表的头指针*/ *tail, /*链表的尾指针*/ *p; int n; char c; h = tail = NULL; printf("Input data. \n"); while (scanf("%d",&n)>0) { /*有整数输入*/ p = (struct intNode *)malloc(sizeof(struct intNode)); p->value = n; p->next = NULL; if (h == NULL) h = tail = p; else tail = tail->next = p; } do { scanf("%c",&c); }while (c!='\n'); /*掠过整数序列之后,回车之前的字符*/ return h; } /*颠倒链表的函数*/ struct intNode * reverse(struct intNode *h) { struct intNode *p,*v1,*v2; v2 = h; /*v2指向链表的首表元*/ v1 = NULL; /*开始颠倒时,已颠倒部分为空*/ while (v2 != NULL) { /*还未颠倒完,循环*/ p = v2->next; /*保存后一个表元*/ v2->next = v1; v1 = v2; v2 = p; } return v1; } /*插入函数--------插入在首结点之前*/ struct intNode *inNode(void) { int d; struct intNode *p; printf("输入插入表元的值[将插入在首结点之前] "); scanf("%d",&d); p = (struct intNode *)malloc(sizeof(struct intNode)); p -> value = d; p -> next = head; return p; } /*删除结点,如果找不到这个值,那么就不做什么*/ struct intNode * delNode(void) { int d; struct intNode *p,*q; printf("输入删除表元的值 "); scanf("%d",&d); p = searchDSLink(head,d,&q); if (p == NULL) printf("没有指定值%d的表元.\n",d); else { if (q == NULL) head = p -> next; /*删除的是第一个结点,首结点*/ else q->next = p->next; p->next = NULL; free(p); } return head; } /*反转链表---前面已经有一个函数了,怎么还来这样的形式,为什么*/ struct intNode * revNode() { return reverse(head); } char * menuName [] = { "创建一个整数链表,输入非整数结束输入","向链表插入 一个新结点","从链表删除一个结点","将链表颠倒",""}; struct intNode * (*fpt[])(void) = { createList,inNode,delNode,revNode,NULL }; /*指向函数的指针数组,所指向的这些函数的返回值是指向struct intNode的指针 */ struct intNode * (*menu(void))(void) /*函数返回函数的指针*/ { int ans,k; printf("请选择以下的菜单命令. \n"); for (k = 0;menuName[k][0] != '\0'; k++) printf("\t%d:%s\n",k+1,menuName[k]); printf("\t其他选择结束程序运行. \n"); scanf("%d",&ans); if (ans <1 || ans > k) return NULL; return fpt[ans -1]; //返回函数的指针 } void main() { struct intNode *(*fp)(void); //必须先定义// head = NULL; while (1) { if ((fp=menu()) == NULL) break; head = (*fp)(); travelLink(head); } }