双循环链表的初始化、查找、插入、删除、定位等操作C语言数据结构(注释详细)
程序员文章站
2024-03-22 11:42:34
...
用C语言定义双循环链表,分别用函数实现下列功能:
{
- 初始化双循环链表;
- 定位运算:在带头结点的双循环链表中查找第i个结点的地址;
- 查找运算:在带头结点的双循环链表中查找其结点值等于x(x的值自己定义)的结点;
- 双循环链表的插入运算:在带头结点的双循环链表中第i个位置插入值为x(x的值自己定义)的新结点;
- 双循环链表的删除运算:在带头结点的双循环链表中删除第i个元素;
}
正在学c语言数据结构的同学最好不要照搬,通过注释自己摸索写出属于自己的代码才是最重要的。
话不多说,直接上代码:
#include<stdio.h>
#include<stdlib.h>
/********************定义节点*********************/
struct node
{
int data;//数据区域
struct node* next;//指针后继区域
struct node* priv;//指针前驱区域
};
/****************定义双循环链表结构******************/
struct singlelink
{
struct node* head;//首节点
struct node* rear;//尾节点
int length;//双循环链表长度
};
/*****************初始化双循环链表/*****************/
void initlink(struct singlelink* link)
{
link->head = (struct node*)malloc(sizeof(struct node));//初始化首节点
link->head->data = 0;//让首元节点的数据域为0
link->length = 0;
}
/********************插入数据*****************/
int insert(struct singlelink* link, int position, int value)
{
int i = 0, j = 0;
struct node* newnode = (struct node*)malloc(sizeof(struct node));
if (position<0 || position>link->length)//判断输入位置是否合法
{
printf("插入的位置超出双循环链表现有范围,请重新输入!\n");
return;//非法,返回上一步操作
}
if (position == 0)//当插入在表头位置时
{
newnode->data = value;//将数据赋值给插入的节点的数据区域
link->head->priv = newnode;//将头节点的直接前驱链接
newnode->next = link->head;//将头结点的NULL值赋值给插入的节点的指针区域,插入值直接后继连接成功
link->head->next = newnode;//将插入节点的地址赋值给头节点的指针区域
newnode->priv = link->head;//将新插入节点的直接前驱链接
}
else//当插入在非表头位置时
{
struct node* first = link->head->next;//first为当前的节点,link->head->next表示头节点
while (i != link->length)//循环自增i,直到判断的i不满足条件时,p指向位置值
{
++i;//数据不匹配,则移到下一节点继续判断
if (i == position)//找到数据,直接输出
{
printf("查找成功!\n该节点数据为:%d,已在该节点后插入元素%d完成\n", first->data, value);
break;
}
first = first->next;//指针后移一位
j++;//长度往下判断一位
}
newnode->data = value;//将输入的值赋给插入的节点的数据区域
first->next = newnode;//将插入节点的地址赋值给上一个节点的指针区域
newnode->priv = first;//将插入节点的直接前继两两链接
newnode->next = link->head->next;//将连接上一个节点的的地址转接给待插入的节点的指针区域
link->head->next->priv = newnode;
}
printf("插入成功!\n");
link->length++;//让双循环链表长度+1
return 1;
}
/********************查找数据**********************/
struct node* find(struct singlelink* link, int position)
{
int i = 0, j = 0;
struct node* first = link->head->next;//first为当前的节点
while (j != link->length)//如果当前的节点没有到结尾,则输出数据
{
if (i == position)//找到数据,直接输出
{
printf("查找成功!\n该节点数据为:%d\n", first->data);
return;
}
first = first->next;//指针后移一位
i++;//数据不匹配,则移到下一节点继续判断
j++;//长度往下判断一位
}
printf("找不到该数据,请检查是否存在该数据\n");
return;//判断完成,仍没有该点,则返回上一步操作
}
/********************删除数据***********************/
void deletelink(struct singlelink* link, int position)
{
struct node* dele;//定义一个待删除的节点
struct node* first = link->head->next;//first为当前的节点
if (position<0 || position>link->length)//判断输入位置是否合法
{
printf("删除的位置超出双循环链表现有范围,请重新输入!");
return;//返回上一步操作
}
if (position == 0)//当删除在表头位置时
{
dele = link->head;
link->head = dele->next;
free(dele);
}
else//当删除在非表头位置时
{
int i = 0, j = 0;
while (i != link->length)//循环自增i,直到判断的i不满足条件时,p指向位置值
{
++i;//数据不匹配,则移到下一节点继续判断
first = first->next;//指针后移一位
if (i == position)//找到数据,直接输出
{
first->priv->next = first->next;
first->next->priv = first->priv;
printf("查找成功!\n该节点数据为:%d,已删除\n", first->data);
free(first);
break;
}
j++;//长度往下判断一位
}
}
link->length--;//双循环链表长度减一
}
/************输出双循环链表中的全部数据***************/
void printlink(struct singlelink* link)
{
int i = 0;
struct node* current = link->head;//将头节点赋值给当前节点current
if (link->length == 0)
printf("该数据表为空,请插入数据后重试!\n");
while (i != link->length)//当current等于自己current->next->priv时,逻辑非值为0,当其不等于NULL时,逻辑非值为1,一直循环
{
printf("[%d]->", current->next->data);
current = current->next;
i++;
}
printf("\n");
}
/********************主测试程序*********************/
int main()
{
//定义双循环链表
int i, j, num, x;
struct singlelink link;
initlink(&link);//初始化双循环链表
while (1)
{
printf("\t提示:系统已自动初始化双循环链表\n\n");
printf("\t\t1.插入节点\n\n");
printf("\t\t2.删除节点\n\n");
printf("\t\t3.查找节点数据\n\n");
printf("\t\t4.输出双循环链表中全部节点数据\n\n");
printf("\t\t5.清空屏幕内容\n\n");
printf("\t\t6.退出程序\n\n");
A: printf("\n\n请选择功能项,并按回车执行:");
scanf("%d", &num);
switch (num)
{
case 1: //插入数据
{
printf("请输入想插入的节点位置(请从0开始逐一输入):\n");
scanf("%d", &i);
printf("请输入想插入的节点数据为:\n");
scanf("%d", &x);
insert(&link, i, x);
goto A;
}
case 2://删除节点
{
printf("请输入你要删除的节点位置为:\n");
scanf("%d", &i);
deletelink(&link, i);
printf("删除成功!\n");
goto A;
}
case 3://查找节点数据
{
struct node* dat;
printf("请输入你想找的节点位置为:\n");
scanf("%d", &x);
find(&link, x);
goto A;
}
case 4://输出双循环链表中全部节点数据
{
printf("该双循环链表的全部节点为:\n");
printlink(&link);
goto A;
}
case 5://清空屏幕内容
{
system("cls");
break;
}
case 6://退出程序
{
system("cls");
printf("退出成功!");
return;
}
}
}
}