实现单链表的诸多功能(头插法,尾插法,查找,增添,删除,替换,排序,释放)
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node* next;
} Node; //创建结构体 struct node 别名Node
/*
头插法:创建指针函数creat1()
*/
Node* creat1(int x)
{
int e;
Node* head, * p; //头指针head,新结点指针p
head = (Node*)malloc(sizeof(node)); //申请表头存储空间
head->next = NULL; //表头指针域置为NULL
printf("请输入%d个任意整数:\n", x);
/*
采用for循环给已知结点个数申请空间,并使结点之间相连
*/
for (int i = 0; i < x; i++)
{
p = (Node*)malloc(sizeof(node));
scanf_s("%d", &e);
p->data = e;
p->next = head->next;
head->next = p;
}
return head;// 单链表返回值(表头结点)head
}
/*
尾插法:创建指针函数creat2();
*/
Node* creat2(int x)
{
int e;
Node* head, * p, * q;//头指针head,并使p指针也指向表头,q指针是最后遍历单链表输出数据时要用
head = (Node*)malloc(sizeof(node));
q = head;
q->next = NULL; //初始表头结点指针域置为空
printf("请输入%d个任意整数:\n", x);
/*
采用for循环给已知结点个数申请空间,并使结点之间相连
*/
for (int i = 0; i < x; i++)
{
p = (Node*)malloc(sizeof(node));
scanf_s("%d", &e);
p->data = e;
q->next = p;
q = p;
}
q->next = NULL;
return head;// 单链表返回值(表头结点)head
}
/*
当在主函数中选用功能1时(头插法),调用此函数
*/
void output1(int n)
{
Node* creat1(int x); //声明单链表头插法函数
void find(int m, Node * pb);//声明查找函数
void replace(int m, Node * pb);//声明替换函数
void insert(int m, Node * pb);//声明插入函数
void cancle(int m, Node * pb);//声明删除函数
void sort1(int m, Node * pb);//声明排序函数(从大到小)
void sort2(int m, Node * pb);//声明排序函数(从小到大)
void clean(Node*pb);//声明释放内存函数
Node* pt = creat1(n);//调用单链表头插法函数,并将返回值head赋给pt
Node* pl = pt; //这里设置指针pl是方便实行单链表其他的功能(实参)
/*
指针pt遍历单链表输出数据
*/
pt = pt->next;
printf("头插法单链表输出数字顺序为:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", pt->data);
pt = pt->next;
}
find(n, pl);//调用查找函数
replace(n, pl);//调用替换函数
insert(n, pl);//调用插入函数
cancle(n,pl);//调用删除函数
sort1(n,pl);//调用排序函数(从大到小)
sort2(n, pl);//调用排序函数(从小到大)
clean(pl);//调用释放内存函数
}
/*
当在主函数中选用功能2时(尾插法),调用此函数
*/
void output2(int n)
{
Node* creat2(int x);//声明单链表尾插法函数
void find(int m, Node * pb);//声明查找函数
void replace(int m, Node * pb);//声明替换函数
void insert(int m, Node * pb);//声明插入函数
void cancle(int m, Node * pb);//声明删除函数
void sort1(int m, Node * pb);//声明排序函数(从大到小)
void sort2(int m, Node * pb);//声明排序函数(从小到大)
void clean(Node*pb);//声明释放内存函数
Node* pt = creat2(n);//调用尾插法函数,并把函数的返回值head赋给pt
Node* pl = pt; //这里设置指针pl是方便实行单链表其他的功能
/*
指针pt遍历链表输出数据
*/
pt = pt->next;
printf("头插法单链表输出数字顺序为:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", pt->data);
pt = pt->next;
}
find(n, pl);//调用查找函数
replace(n, pl);//调用替换函数
insert(n, pl);//调用插入函数
cancle(n, pl);//调用删除函数
sort1(n, pl);//调用排序函数(从大到小)
sort2(n, pl);//调用排序函数(从小到大)
clean(pl);//调用释放空间函数
}
/*
查找链表中固定位置数据
*/
void find(int m,Node*pb)
{
int i;
int j = 0;
printf("\n请输入你想查询的的位置(范围:1-%d):\n",m);
scanf_s("%d", &i);
if (i > 0 && i <= m)
{
while (i!=j)
{
pb = pb->next;
j++;
}
printf("查询正确:%d", pb->data);
}
else printf("你输入的数字不在范围:(1-%d),查询失败",m);
}
/*
链表中数据的替换
*/
void replace(int m,Node*pb)
{
int j=0;
int i,e;
Node* pc = pb;//创建指针pc也指向表头结点,用指针pb查找指定位置进行替换,用pc指针遍历链表输出替换后数据
printf("\n请输入你要替换的位置(范围:1-%d):\n", m);
scanf_s("%d",&i);
if (i > 0 && i <= m)
{
while (i != j)
{
pb = pb->next;
j++;
}
printf("请输入你想要替换的数字:\n");
scanf_s("%d",&e);
pb->data = e;
printf("替换数据成功,输出链表结果为:\n");
pc = pc->next;
for (int j=0;j<m;j++)
{
printf(" %d ", pc->data);
pc= pc->next;
}
}
else printf("你要替换的位置不在范围:(1-%d)内\n", m);
}
/*
链表中插入数据
*/
void insert(int m,Node*pb)
{
int i,e;
int j = 1;
Node* pc = pb;//创建指针pc指向表头结点,指针pb查找插入位置,并进行插入,指针pc遍历单链表输出插入后的数据
Node* p;
printf("\n请输入你要插入的位置(范围:1—%d):\n",m+1);
scanf_s("%d",&i);
if (i >= 1 && i <= m + 1)
{
while (pb && i != j)
{
pb = pb->next;
j++;
}
p = (Node*)malloc(sizeof(node));
printf("请输入你要插入的数据:\n");
scanf_s("%d",&e);
p->data = e;
p->next = pb->next;
pb->next = p;
printf("插入数据成功,输出链表结果:\n");
pc = pc->next;
while (pc!=NULL)
{
printf("%d ",pc->data);
pc = pc->next;
}
}
else printf("\n你要插入的位置不在范围(范围:1—%d)",m+1);
}
/*
单链表指定位置删除
*/
void cancle(int m, Node* pb)
{
int i;
int j = 0;
/*
创建指针pc,p都指向表头结点:
指针pc,pb是用来查找删除位置,并进行删除指定位置结点之后对结点进行连接
指针p是用来遍历单链表输出删除后数据
*/
Node* pc = pb;
Node* p = pb;
printf("\n请输入你要删除数据的位置 (范围:1-%d):\n", m + 1);
scanf_s("%d", &i);
if (i >= 1 && i <= m + 1)
{
while (j != i - 1)
{
pc = pb->next;
pb = pc;
j++;
}
pc = pb->next;
pb->next = pc->next;
free(pc);
printf("数据清除成功,输出链表结果:\n");
while (p->next)
{
p = p->next;
printf("%d ", p->data);
}
}
else printf("你删除的位置不在范围(范围:1—%d)\n", m + 1);
}
/*
单链表排序(冒泡法:效率高)
*/
void sort1(int m, Node* pb)//从大到小排序
{
int i, j, n;
Node* pc=pb;//指针pc指向表头结点
for (i = 0; i < m - 1; i++)
{
for (j = 0; j < m-i-1; j++)
{
pc=pc->next;
if (pc->data < pc->next->data)
{
n = pc->next->data;
pc->next->data = pc->data;
pc->data = n;
}
}
pc = pb;
}
pb = pb->next;
printf("\n单链表从大到小的顺序为:\n");
for (i=0;i<m;i++)
{
printf("%d ",pb->data);
pb = pb->next;
}
}
void sort2(int m, Node* pb)//从小到大排序
{
int i, j, n;
Node* pc = pb;//指针pc指向表头结点
for (i = 0; i < m - 1; i++)
{
for (j = 0; j < m - i - 1; j++)
{
pc = pc->next;
if (pc->data > pc->next->data)
{
n = pc->next->data;
pc->next->data = pc->data;
pc->data = n;
}
}
pc = pb;
}
pb = pb->next;
printf("\n单链表从小到大的顺序为:\n");
for (i = 0; i < m; i++)
{
printf("%d ", pb->data);
pb = pb->next;
}
}
/*
链表释放(需要两个指针)
*/
void clean(Node*pb)
{
Node* pc = pb;//指针pc指向表头结点
while (pb!=NULL)
{
pc = pb->next;
free(pb);
pb = pc;
}
printf("\n单链表存储空间已释放\n");
}
/*
主函数
*/
int main()
{
int m;
int n;
void output1(int n);//声明头插法中诸多功能函数
void output2(int n);//声明尾插法中诸多功能函数
printf("\n1.头插法建立链表\n2.尾插法建立链表\n");
printf("\n请输入选择操作的数字:\n");
scanf_s("%d", &m);
printf("请输入你要输入数字的个数:\n");
scanf_s("%d", &n);
/*
功能判断:
如果m=1,调用 头插法中诸多功能函数
如果m=2,调用 尾插法中诸多功能函数
*/
if (m == 1) output1(n);
if (m == 2) output2(n);
return 0;
}
运行结果:
如果有什么地方不合适的话,还请指正哈!!!