单循环链表的相关操作

tech2024-10-14  10

单循环链表的相关操作

#include<stdio.h> #include<stdlib.h> #include<time.h> typedef struct LinkListNode { int data; struct LinkListNode* next; }node,*LinkList; //结构体变量类型 void GreatLinklistTail(LinkList* head); // 建立链表 void LinkListInsert(LinkList* head); //插入节点 void LinkListFind(LinkList* head); //查找数据 void LinkListnode_Delete(LinkList* head); //删除节点 void LinkListDatePrint(LinkList* head); //链表的输出 void LinkListClean(LinkList* head); //链表的整表删除 /** *为了建立、使用、维护链表,对链表的操作如下: *建立链表 *遍历链表 *尾部追加 *删除结点 *查找结点 */ /******************************************************************************/ int main(void) { LinkList head; int i; printf("*************************单循环链表操作***************************\n\n"); printf("1.初始化循环链表\n\n2.插入节点 \n\n3.删除节点 \n\n4,查找节点\n\n0.释放内存操作完成\n\n"); while(1) { scanf("%d", &i); switch(i) { case 1: { printf("下面进行建立链表操作!\n"); GreatLinklistTail(&head); LinkListDatePrint(&head); } break; case 2: { printf("下面进行插入节点操作!\n"); LinkListInsert(&head); LinkListDatePrint(&head); } break; case 3: { printf("下面进行删除节点操作!\n"); LinkListnode_Delete(&head); LinkListDatePrint(&head); } break; case 4: { printf("下面进行查找数据操作!\n"); LinkListFind(&head); } break; } if(i == 0) { break; } } printf("链表操作结束!\n"); LinkListClean(&head); system("pause"); return 0; } /**********************************************************************************/ //单循环链表初始化操作 void GreatLinklistTail(LinkList* head) { node *p, *target = NULL; //声明节点p 和遍历结构体指针变量 target int i, j; *head = (LinkList)malloc(sizeof(LinkList)); //为第一个节点开辟内存 (*head)->next = *head; //将第一个指针的next 指向第一个节点 target = *head; //令遍历指针 指向第一个节点 printf("请输入所要开辟节点的个数,输入0退出: \n"); scanf_s("%d", &i); fflush(stdin); if(i == 0) { return ; //如果输入 0直接退出程序 } if (i == 1)//当只要开辟一个节点的时候 令第一个节点的next指向自身形成循环链表 { printf("请输入要存储的值:"); scanf_s("%d", &(*head)->data); fflush(stdin); (*head)->next = *head; //令第一个节点的next指向自身形成循环链表 printf("单循环链表建立完毕!!!\n\n"); } else { for (j = 1; j <= i; j++) { if(j == 1) //开辟第一个节点时 { printf("请输入第%d个节点所要存储的数据:", j); p = *head; //令p指向第一个节点 便于操作 scanf_s("%d", &p->data); p->next = p; //令第一个节点的next指向 自身 } else //第一个节点建立结束后 { p = (node*)malloc(sizeof(node)); //为新节点开辟节点 if (!p) { exit(0); //分配内存失败退出 } printf("请输入第%d个节点所要存储的数据:", j); scanf_s("%d", &p->data); p->next = target->next; //先后继再前驱原则,令p的next指向第一结点 target->next = p; //将上一个节点的next 指向p target = p; //遍历节点向后移位 } } } printf("单链表建立完毕!!!\n\n"); } //打印数据函数 //链表数据的输出 /*思路: 1,开辟一个节点p 2,令节点p指向第一个节点 3,通过循环打印出每个节点的值 */ void LinkListDatePrint(LinkList *head) //输出循环链表的所有元素 { node *p; int j = 1; p = *head; printf("********************链表中的数据********************\n"); do // 不可用 当型循环 { printf("第%d个节点存储的数为:%4d;\n", j , p->data); p = p->next; //循环遍历链表算法 j++; }while(p != *head); //遍历到最后一个节点为止 printf("链表数据打印完毕!!!\n\n"); } //链表的整表删除 /*思路: 1,声明节点p,q 2,将第一个节点赋给p,下一个赋给 q 3,循环执行释放p和将q赋给p操作 */ void LinkListClean(LinkList* head) { node* p, * q; p = *head; while (p->next != (*head)) //循环释放法则 { q = p->next; free(p); p = q; } printf("单链表内存释放成功!!!\n"); } //链表的数据插入操作 void LinkListInsert(LinkList* head) //插入节点 { node *p, *s; //声明循环遍历结构体指针p 和 插入节点 s int i, j = 1; s = (node*)malloc(sizeof(node)); //为要插入的节点开辟内存 s->next = NULL; //防止成为野指针 p = *head; //令循环节点指向头结点 printf("请输入要插入的节点的位置:"); scanf_s("%d", &i); fflush(stdin); if (i == 1) { printf("请输入第%d个节点要插入的值:\n", i); scanf_s("%d", &s->data); //赋值操作 fflush(stdin); for(p = *head; p->next != *head; p= p->next) ; //寻找最后一个节点 s->next = *head; //先后继 p->next = s; //尾节点指向s 后前驱 算法 *head = s; //把head 再次换成第一个节点 } else { for (j = 1; j < i-1; j++) { p = p->next; 将循环指针指向 要插入的前一个节点 } printf("请输入第%d个节点要插入的值:\n", i); scanf_s("%d", &s->data); fflush(stdin); s->next = p->next;//令插入的节点的next指向原本的第 i个节点 //先后继 p->next = s; //后前驱 printf("\n"); } printf("节点插入成功!!!\n\n"); } //节点的查找并返回节点的位置 /* 思路: 1,声明节点 p,开辟节点,指向头结点 2, 声明计数器j 和存储数据的 容器 3, 循环查找 */ void LinkListFind(LinkList* head) //查找第i个元素 { node *target; int i, j = 1; printf("请输入查找的数据:"); scanf_s("%d", &i); fflush(stdin); for (target = *head; target->data != i && target->next != *head; target = target->next) j++; //循环遍历寻找最后一个节点 printf("该节点的位置是: %d\n\n", j); } //单链表节点删除操作 void LinkListnode_Delete(LinkList* head) { node *p, *target = NULL; //声明节点p指向链表的第一个节点 int i; //要删除的节点 int j = 1; //声明一个计数器 p = *head; //p节点指向第一个节点 printf("请输入要删除的节点标号:"); scanf_s("%d", &i); fflush(stdin); if (i == 1) { for (target = *head; target->next != (*head); target = target->next) ; //循环遍历寻找最后一个节点 p = *head; *head = (*head)->next; target->next = *head; free(p); } else { target = *head; for (; j < i - 1; j++) //寻找要删除节点的前一位 { target = target->next; } p = target->next; //将p 指向要删除的节点, target->next = p->next; //使前一个节点指向后一个节点 free(p); printf("节点删除成功!!!!\n\n"); } }
最新回复(0)