单循环链表的相关操作
#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");
}
}