#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <windows.h> /**********双向链表节点**********/ 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; }