#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;
}
}