以下用C语言来创建单链表,并分别用函数实现下列功能:
{
- 初始化单链表;
- 定位运算:在带头结点的单链表中查找第i个结点的地址;
- 查找运算:在带头结点的单链表中查找其结点值等于x(x的值自己定义)的结点;
- 单链表的插入运算:在带头结点的单链表中第i个位置插入值为x的新结点;
- 单链表的删除运算:在带头结点的单链表中删除第i个元素;
}
正在学c语言数据结构的同学最好不要照搬,通过注释自己摸索写出属于自己的代码才是最重要的。
话不多说,直接上代码:
#include<stdio.h>
#include<stdlib.h>
/********************定义节点********************/
struct node
{
int data;//数据区域
struct node* next;//指针区域
};
/**************定义链表结构********************/
struct singlelink
{
struct node* head;//首节点
int length;//链表长度
};
/********************初始化链表/******************/
void initlink(struct singlelink* link)
{
link->head = NULL;//初始化首节点为NULL
link->length = 0;
}
/********************插入数据********************/
int insert(struct singlelink* link, int position, int value)
{
int i = 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;//将数据赋值给插入的节点的数据区域
newnode->next = link->head;//将头结点的NULL值赋值给插入的节点的指针区域,插入值直接后继连接成功
link->head = newnode;//将插入节点的地址赋值给头节点的指针区域
}
else//当插入在非表头位置时
{
struct node* privious;//定义一个privious作为插入点前驱,并将当前输入的位置减一以找到直接前驱
while (i < position-1)//循环自增i,直到判断的i不满足条件时,p指向位置值
{
link->head = link->head->next;//p指向的头节点为NULL
i++;
}
privious = link->head;
newnode->data = value;//将输入的值赋给插入的节点的数据区域
newnode->next = privious->next;//将连接上一个节点的的地址转接给待插入的节点的指针区域
privious->next = newnode;//将插入节点的地址赋值给上一个节点的指针区域
}
printf("插入成功!\n");
link->length++;//让链表长度+1
return 1;
}
/********************查找数据****************/
struct node* find(struct singlelink* link, int position)
{
int i=0;
struct node* current = link->head;//current为当前的节点
while (current != NULL)//如果当前的节点没有到结尾,则输出数据
{
if (i == position)//找到数据,直接输出
{
printf("查找成功!\n该节点数据为:%d\n", current->data);
return;
}
i++;//数据不匹配,则移到下一节点继续判断
}
printf("找不到该数据,请检查是否存在该数据\n");
return;//判断完成,仍没有该点,则返回上一步操作
}
/********************删除数据*******************/
void deletelink(struct singlelink* link, int position)
{
struct node* dele;
if (position<0 || position>link->length - 1)//判断输入位置是否合法
{
printf("删除的位置超出链表现有范围,请重新输入!");
return;//返回上一步操作
}
if (position == 0)//当插入在表头位置时
{
dele = link->head;
link->head = dele->next;
free(dele);
}
else//当插入在非表头位置时
{
struct node* privious = find(link, position - 1);//先找到当前位置的前驱
dele = privious->next;//定位要删除的节点
privious->next = dele->next;//将前一个节点定位到下一个节点
free(dele);
}
link->length--;//链表长度减一
}
/********************释放链表********************/
void freelink(struct singlelink* link)
{
struct node* p = link->head->next;//通过结构体内嵌的方法,调用了node结构体的数据
while (p)//判断链表是否为空值,若为非NULL值则循环执行
{
link->head->next = p->next;//通过头节点找到下一个节点
free(p);
p = link->head->next;
}
link->length = 0;//让链表长度为0
link->head = NULL;//释放头节点
}
/*****************输出链表中的全部数据***************/
void printlink(struct singlelink* link)
{
struct node* current = link->head;//将头节点赋值给当前节点current
if (current == NULL)
printf("该数据表为空,请插入数据后重试!\n");
while (current != NULL)//当current->next等于NULL时,逻辑非值为0,当其不等于NULL时,逻辑非值为1,一直循环
{
printf("[%d]->", current->data);
current = current->next;
}
printf("\n");
}
/********************修改节点数据********************/
void modifynode(struct singlelink* link,int position,int data)
{
int i = 0;
struct node* current = link->head;//current为当前的节点
while (current != NULL)//如果当前的节点没有到结尾,则输出数据
{
if (i == position)//找到数据,直接输出
{
printf("修改成功!\n该节点原数据为%d\n数据修改为:%d\n", current->data,data);
current->data = data;
return;
}
i++;//数据不匹配,则移到下一节点继续判断
current=current->next;
}
printf("找不到该数据,请检查是否存在该数据\n");
return;//判断完成,仍没有该点,则返回上一步操作
}
/********************主测试程序*******************/
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");
printf("\t\t7.退出程序\n\n");
printf("请选择功能项,并按回车执行:");
scanf("%d", &num);
switch (num)
{
case 1: //插入数据
{
printf("请输入想插入的节点位置(请从节点0开始逐一输入):\n");
scanf("%d", &i);
printf("请输入想插入的节点数据为:\n");
scanf("%d", &x);
insert(&link, i, x);
system("pause");
system("cls");
break;
}
case 2://删除节点
{
printf("请输入你要删除的节点位置为:\n");
scanf("%d", &i);
deletelink(&link, i);
printf("删除成功!\n");
system("pause");
system("cls");
break;
}
case 3://查找节点数据
{
struct node* dat;
printf("请输入你想找的节点位置为:\n");
scanf("%d", &x);
find(&link, x);
system("pause");
system("cls");
break;
}
case 4://输出顺序表中全部节点数据
{
printlink(&link);
system("pause");
system("cls");
break;
}
case 5://修改节点数据
{
printf("请输入你想修改的数据位置为:\n");
scanf("%d", &i);
printf("该数据修改为:\n");
scanf("%d", &x);
modifynode(&link,i,x);
printf("修改成功!\n");
system("pause");
system("cls");
break;
}
case 6://释放链表
{
freelink(&link);
printf("释放完成!现在该链表回归大自然的拥抱啦!\n");
system("pause");
system("cls");
break;
}
case 7://退出程序
{
system("cls");
printf("退出成功!");
return;
}
}
}
}