#include <stdio.h> #include <malloc.h> #include <stdlib.h> #define MAXSIZE 1000 typedef int ElemType; typedef struct node{ //定义链表节点类型 ElemType data; struct node * next; } Node; typedef Node *LinkedNode; /*[1] 求以h为头指针的单链表的节点个数 */ int GetNodeNum(LinkedNode &h) { if(h==NULL) return 0; else return GetNodeNum(h->next) + 1; } /*[2] 正向显示以h为头指针的单链表的所有节点值 */ void PrintForward(LinkedNode &h) { if(h==NULL) //链表到头,结束输出 return ; printf("%d ",h->data); PrintForward(h->next); //输出下一个元素值 } /*[3] 反向显示以h为头指针的单链表的所有节点值 */ void PrintReverse(LinkedNode &h) { if(h==NULL) return ; PrintReverse(h->next); //链表跑到头,再开始输出 printf("%d ",h->data); } /*[4] 删除以h为头指针的单链表中值为x的第一个节点 */ bool DeleteFirstX(LinkedNode &h,ElemType x) { //递归出口 if(h==NULL) return false; else if(h->data==x){ //第一个节点就是要找的节点,删除 if(h->next==NULL){ //只有一个节点 free(h); h = NULL; return true; } LinkedNode p; p = h; h = h->next; free(p); return true; } else if(h->next!=NULL){ if(h->next->data==x){ //找到节点,删除 LinkedNode p; p = h->next; h->next = p->next; free(p); return true; } } //递归体 if(DeleteFirstX(h->next,x)) return true; else return false; } /*[5] 删除以h为头指针的单链表中值为x的所有节点 */ void DeleteAllX(LinkedNode &h,ElemType x) { if(h==NULL) return ; if(h->data==x){ //第一个节点就是要找的节点,删除 if(h->next==NULL){ //只有一个节点 free(h); h = NULL; return ; } LinkedNode p; p = h; h = h->next; free(p); DeleteAllX(h,x); } else if(h->next==NULL) //递归出口 return ; else if(h->next->data==x){ //找到节点,删除 LinkedNode p; p = h->next; h->next = p->next; free(p); DeleteAllX(h,x); } else DeleteAllX(h->next,x); } /*[6] 删除以h为头指针的单链表中最大节点值 */ void DeleteMaxNode(LinkedNode &h,LinkedNode c,LinkedNode p) { if(h==NULL) return ; if(c->next==NULL){ //到头,开始删除 if(p->next ==NULL){ free(p); h = NULL; return ; } if(p==h && p->data > p->next->data){ //第一个节点是要删除的节点 h = h->next; free(p); return ; } else{ LinkedNode q = p->next; p->next = q->next; free(q); return ; } } if(c->next->data > p->next->data) p = c; DeleteMaxNode(h,c->next,p); } /*[7] 删除以h为头指针的单链表中最小节点值 */ void DeleteMinNode(LinkedNode &h,LinkedNode c,LinkedNode p) { if(h==NULL) return ; if(c->next==NULL){ //到头,开始删除 if(p->next ==NULL){ free(p); h = NULL; return ; } if(p==h && p->data < p->next->data){ //第一个节点是要删除的节点 h = h->next; free(p); return ; } else{ LinkedNode q = p->next; p->next = q->next; free(q); return ; } } if(c->next->data < p->next->data) p = c; DeleteMinNode(h,c->next,p); } /* 1. 初始化单链表 */ LinkedNode LinkedListInit() { LinkedNode head = (Node*)malloc(sizeof(Node)); head->next = NULL; return head; } /* 2. 清空单链表 */ void LinkedListClear(LinkedNode &L) { //L为头指针 while(L){ //依次清空节点,直到头指针指向的下一个节点的地址为空 LinkedNode t; t = L; L = t->next; free(t); } return ; } /* 3. 用尾插法建立单链表 */ LinkedNode LinkedListCreat( LinkedNode L,ElemType a[],int n ) //讲数组a中的元素以尾插法放入链表中 { int i; LinkedNode p = L; p->data = a[1]; for(i=2;i<=n;i++){ LinkedNode q = (LinkedNode)malloc(sizeof(Node)); q->data = a[i]; q->next = NULL; p->next = q; p = q; } return L; } int Menu() { int in; printf("[1] 重新建立一个链表\n"); printf("[2] 求以h为头指针的单链表的节点个数\n"); printf("[3] 正向显示以h为头指针的单链表的所有节点值\n"); printf("[4] 反向显示以h为头指针的单链表的所有节点值\n"); printf("[5] 删除以h为头指针的单链表中值为x的第一个节点\n"); printf("[6] 删除以h为头指针的单链表中值为x的所有节点\n"); printf("[7] 删除以h为头指针的单链表中最大节点值\n"); printf("[8] 删除以h为头指针的单链表中最小节点值\n"); printf("[0] 按其他键退出\n"); scanf("%d",&in); return in; } LinkedNode Reply(LinkedNode head,int in) { int i,n,x; int a[MAXSIZE+1]; switch(in){ case 1: //重新建立一个链表 LinkedListClear(head); head = LinkedListInit(); printf("你要输入多少个数据?\n"); scanf("%d",&n); //输入链表大小 printf("请依次输入数据:\n"); for(i=1;i<=n;i++) scanf("%d",&a[i]); head = LinkedListCreat(head,a,n); printf("链表建立成功!\n"); break; case 2: //求以h为头指针的单链表的节点个数 printf("单链表的节点个数为:%d\n",GetNodeNum(head)); break; case 3: //正向显示以h为头指针的单链表的所有节点值 printf("链表中元素依次为(正向):\n"); PrintForward(head); printf("\n"); break; case 4: //反向显示以h为头指针的单链表的所有节点值 printf("链表中元素依次为(反向):\n"); PrintReverse(head); printf("\n"); break; case 5: //删除以h为头指针的单链表中值为x的第一个节点 printf("输入你要删除的元素的值?\n"); scanf("%d",&x); if(DeleteFirstX(head,x)) printf("删除成功!\n"); else printf("删除失败!\n"); printf("链表中元素依次为(正向):\n"); PrintForward(head); printf("\n"); break; case 6: //删除以h为头指针的单链表中值为x的所有节点 printf("输入你要删除的元素的值?\n"); scanf("%d",&x); n = GetNodeNum(head); DeleteAllX(head,x); i = GetNodeNum(head); if(n!=i) printf("删除成功!\n"); else printf("删除失败!\n"); printf("链表中元素依次为(正向):\n"); PrintForward(head); printf("\n"); break; case 7: //删除以h为头指针的单链表中最大节点值 n = GetNodeNum(head); DeleteMaxNode(head,head,head); i = GetNodeNum(head); if(n!=i) printf("删除成功!\n"); else printf("删除失败!\n"); printf("链表中元素依次为(正向):\n"); PrintForward(head); printf("\n"); break; case 8: //删除以h为头指针的单链表中最小节点值 n = GetNodeNum(head); DeleteMinNode(head,head,head); i = GetNodeNum(head); if(n!=i) printf("删除成功!\n"); else printf("删除失败!\n"); printf("链表中元素依次为(正向):\n"); PrintForward(head); printf("\n"); break; default: printf("Bye~\n"); exit(1); } system("pause"); system("cls"); return head; } int main() { int in; //存储输入命令 LinkedNode head = NULL; while(1){ in = Menu(); head = Reply(head,in); //响应命令 } return 0; }
时间: 2024-11-05 22:51:48