/**********双向链表节点**********/
typedef struct student
{
int num;
float score;
struct student *prior;
struct student *next;
}TYPE;
int nod_num; //节点数
#define LEN sizeof(TYPE) //节点长度
/*=================================================
函数功能: 创建双向链表
返 回 值: 双向链表的头指针
=================================================*/
TYPE* create_link(void)
{
TYPE *head = NULL;
TYPE *p1,*p2;
nod_num = 0;
p1 = p2 = (TYPE *)malloc(LEN);
printf("input the %d node--num,score!/n",(nod_num+1));
scanf("%d,%f",&(p1->num),&(p1->score));
while(p1->num != 0)
{
nod_num++;
if(nod_num == 1)
{
head = p1;
head->prior = NULL; //首节点的两个指针为NULL
head->next = NULL;
}
else
{
p1->prior = p2;
p2->next = p1;
}
p2 = p1;
p1 = (TYPE *)malloc(LEN);
printf("input the %d node--num,score!/n",(nod_num+1));
scanf("%d,%f",&(p1->num),&(p1->score));
}
p2->next = head;
return head;
}
/*=============================================================
实现功能: 打印指定链表中的全部节点数据,由于循环双向表
没有头节点,每个节点性质完全一样,只要给出任
意节点就可以遍历.
参 数: *head:待打印的链表首址
特别说明: 链表正向输出(从链表头遍历到链表尾)
=============================================================*/
void nextprint(TYPE *node)
{
TYPE *pb = node;
printf("/n链表所有信息如下:/n");
if (pb == NULL)
{
printf("/n");
return;
}
while(pb->next != node)
{
printf("%x/t/t%d/t/t%f/n",pb,pb->num,pb->score);
pb=pb->next;
}
printf("%x/t/t%d/t/t%f/n",pb,pb->num,pb->score);
}
/*=============================================================
实现功能: 打印指定链表中的全部节点数据,由于循环双向表
没有头节点,每个节点性质完全一样,只要给出任
意节点就可以遍历.
参 数: *head:待打印的链表首址
特别说明: 链表反向输出(从链表尾遍历到链表头)
=============================================================*/
void PriorPrint(TYPE *node)
{
TYPE *p = node;
if(p != NULL)
{
while(p->next != node)
p = p->next;
while(p != NULL)
{
printf("num=%d,score=%f/n",p->num,p->score);
p = p->prior;
}
}
}
/*================================================
函数功能: 遍历双向链表,目的是测试链表是否成环
函数参数: 双向链表的首地址
返 回 值: 无
================================================*/
void testprint(TYPE *head)
{
TYPE *p;
printf("/nnow,these %d records are:/n",nod_num);
p=head;
if(head!=NULL)
{
do
{
printf("%d %f/n",p->num,p->score);
Sleep(2000);
p=p->next;
}
while (p!=NULL);
}
}
/*=========================================
语法格式: search(TYPE * head,int num)
实现功能: 搜索给定序号所指向的节点
参 数: *head 待搜索链表
num 按所需进行节点搜索
返 回 值: 搜索到的节点首址
=========================================*/
TYPE * search(TYPE * head,int num)
{
TYPE *pb=head;
if(head == NULL)
{
return head;
}
while((pb->num != num)&&(pb->next!=head))
{
pb=pb->next; //节点后移
}
if (pb->num == num)
{
return pb;
}
else
{
printf("/n节点没有找到/n");
return head;
}
}
/*=====================================================================
实现功能: 将新申请的节点加入到指定链表中,并按照num进行从小到大排序
参 数: *head:待插入链表
* pi:带插入节点
返 回 值: 插入指定节点后的新链表首址
=====================================================================*/
TYPE * insert(TYPE * head,TYPE * pi)
{
TYPE *pb=head ,*pf;
if(head==NULL)//如果为空就建立,空间在传入前申请好
{
head=pi;
pi->prior=head;
pi->next=head;
}
else
{
while((pi->num > pb->num)&&(pb->next!=head)) //找到一个比插入值大的节点,然后插在它的前面
{
pf=pb; //pf指向前,pb指向后
pb=pb->next; //节点后移
}
if(pi->num <= pb->num) //找到所要插入节点位置,插到pb的前面
{
if(head==pb) //在第一结点之前插入
{
pi->next = pb;
pi->prior = head->prior;
pb->prior = pi;
head->prior->next = pi; //尾节点
head=pi; //保存头节点
}
else
{
pf->next = pi; //在中间位置插入
pb->prior = pi;
pi->next = pb;
pi->prior = pf;
}
}
else //只有pb->head为空才会成立
{
pb->next = pi; //在表末插入
pi->next = head;
pi->prior = pb;
head->prior = pi; //头始终指向新插入的节点
}
}
return head;
}
/*=============================================================
实现功能: 删除给定序号所指向的节点
参 数: *head 待删除链表
num 所需删除的节点
返 回 值: 删除指定节点后的新链表首址
=============================================================*/
TYPE * delete(TYPE * head,int num)
{
TYPE *pf,*pb = head;
if(head==NULL)
{
printf("/nempty list!/n");
return NULL;
}
while (pb->num!=num && pb->next!=head)
{
pf=pb;
pb=pb->next;
}
if(pb->num==num)
{
if(pb==head)
{
if (pb->next == head && pb->prior == head) //如果只有一个节点
{
free(pb);
head = NULL;
return NULL;
}
pb->next->prior = head->prior; //头节点指向尾
head->prior->next = pb->next; //尾节点指向头
head=pb->next; //得到新头节点地址
}
else
{
pf->next = pb->next;
pb->next->prior = pf;
}
free(pb);
printf("The node is deleted/n");
}
else
printf("The node not been found!/n");
return head;
}
/******************测试函数*******************/
int main(void)
{
TYPE *head=NULL;
TYPE *Lsearch=NULL;
TYPE *ins=NULL;
int searnum;
int delnum;
//创建链表
head = create_link();
//输出链表(正向、反向、测试输出)
nextprint(head); //(正向)打印创建的链表
//PriorPrint(head); //(反向)打印创建的链表
//testprint(head);
//查寻链表
printf("input search Number:/n");
scanf("%d",&searnum);
Lsearch = search(head,searnum);
nextprint(Lsearch); //从搜索到的节点开始打印
//插入链表
ins = (TYPE *)malloc(sizeof(TYPE));
printf("insert Number and Age:/n");
scanf("%d,%f",&(ins->num),&(ins->score));
head = insert(head,ins);
nextprint(head); //打印插入节点后的链表
//删除链表
printf("input delete Number:/n");
scanf("%d",&delnum);
head = delete(head,delnum);
nextprint(head); //打印删除一个节点后的链表
return 0;
}