#include <stdio.h> #include <stdlib.h> typedef struct DulNode *Node; //定义结点 struct DulNode{ int num; int data; Node next,proir; }; /*创建链表 */ Node creatList() { Node head,p,newNode;//注:头结点的定义,在第一个结点之前附设一个结点,头结点数据域可以不存储任何信息,指针域用了存储第一个和最后一个结点的地址 int i,n; printf("请输入链表的长度:\n"); scanf("%d",&n); if((head=(Node)malloc(sizeof(Node))) != NULL);//为结点申请空间,即初始化头结点 head->data=0; head->next=NULL; head->proir=NULL; p=head;//姑且认为头结点是0结点,头结点不是第一个结点,在头结点插入第一个结点 if(n!=0) { for(i=0;i<n;i++) { newNode=(Node)malloc(sizeof(Node)); p->next=newNode; printf("请输入%d个结点的编号和数值:\n",i+1); scanf("%d%d",&newNode->num,&newNode->data); newNode->proir=p;//不要写成p=newNode->proir,是有区别的 p=newNode;//p来标志新结点插入的位置; } head->proir=newNode;//循环链表,头的前驱指向尾 newNode->next=head;//尾的后继指向头 } return head; } /*输出链表内容*/ Node printList(Node head) { Node p; if(head->next==NULL) { printf("链表为空\n"); } else { p=head->next;//从第一个结点开始 while(p!=head) { printf("编号%d的数值为%d\n",p->num,p->data); p=p->next; } } } /* 查询链表*/ Node searchList(Node head) { Node p; int n,flag=0;//用flag来标志是否有编号 if(head->next==NULL) { printf("链表为空\n"); } else { p=head->next; printf("请输入结点的编号:\n"); scanf("%d",&n); while(p!=head) { if(p->num==n) { printf("编号%d的数值为%d\n",p->num,p->data); flag=1; } p=p->next; } if(flag==0) printf("链表无此编号!\n"); /*另一种循环方法*/ /*for(p;p->num!=n&&p!=head;p=p->next); if(n==p->num) printf("查询的编号和数值为:%d,%d \n",p->num,p->data); else printf("未找到相关数据!\n"); */ } return head; } /*删除链表*/ Node delList(Node head) { Node p; int n; if(head->next==NULL) { printf("链表为空\n"); } else { p=head->next;//必须先初始化 printf("请输入删除结点的编号:\n"); scanf("%d",&n); while(p!=head) { if(p->num==n) { p->proir->next=p->next;//p的先驱结点的下个结点 p->next->proir=p->proir;//p的后继结点的先驱结点 } p=p->next; } } return head; } /*添加结点*/ Node insertList(Node head) { Node p,newNode; int i,flag=0; newNode=(Node)malloc(sizeof(Node)); /*链表为空时*/ if(head->next==NULL) { printf("当前链表为空,将创建第一个结点,请输入第一个结点的编号和值:\n"); scanf("%d%d",&newNode->num,&newNode->data); head->next=newNode; head->proir=newNode; newNode->proir=head; newNode->next=head; } else { p=head->next; printf("请输入插在编号为多少的结点后面\n"); scanf("%d",&i); while(p!=head) { if(p->num==i) { printf("请输入结点的编号和数值\n"); scanf("%d%d",&newNode->num,&newNode->data); newNode->proir=p; p->next->proir=newNode; newNode->next=p->next; p->next=newNode;//请注意p->next要先使用再对其赋值 flag=1; } p=p->next; } if(flag==0) printf("编号没有找到\n"); } return head; } /*修改结点*/ Node modifyList(Node head) { Node p; int n,m,flag=0; if(head->next==NULL) { printf("链表为空\n"); } else { p=head->next; printf("请输入修改的编号:\n"); scanf("%d",&n); while(p!=head) { if(p->num==n) { printf("请输入修改的值:\n"); scanf("%d",&m); p->data=m; flag=1; } p=p->next; } if(flag==0) printf("链表无此编号!\n"); } return head; } int main(void) { Node head; head=(Node)malloc(sizeof(Node));//必须初始化头结点,否则在没创建链表是运行其他选项程序错误; head->data=0; head->next=NULL; head->proir=NULL; while(1) { int c; int s=1; printf(".........菜单........\n1.创建链表 2.添加 3.删除 4.修改 5.查询 6.输出内容 0.退出\n"); scanf("%d",&c); switch(c) { case 0: s=0; break; case 1: head=creatList(); break; case 2: insertList(head); break; case 3: delList(head); break; case 4: modifyList(head); break; case 5: searchList(head); break; case 6: printList(head); break; default: printf("输入有误\n"); break; } if(s==0) break; } }