单链表的创建、插入、删除、排序以及逆置
链表中的数据是以节点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
下面将给出单链表的创建、插入、删除、排序以及逆置的思想和代码。
(一)单链表的创建及输出
(1),链表节点的数据结构定义
typedef struct student //定义链表数据结构
{
intdata;
structstudent *next;
}node;
(2)链表的创建
1 ) 定义链表的数据结构;
2 ) 创建一个空表;
3 ) 利用malloc ( )函数向系统申请分配一个节点;
4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新
节点接到表尾;
5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;
//链表的创建
node *createnode()
{
node *head, *p, *s;
int x, flag = 1;
head =(node*)malloc(sizeof(node));
p = head;
while (flag)
{
printf("\n Pleaseinput the data:");
scanf_s("%d",&x);
if (x != 0)
{
s =(node*)malloc(sizeof(node));
s->data = x;
printf("\n%d", s->data);
p -> next = s;
p = s;
}
else flag = 0;
}
head = head->next;
p->next = NULL;
printf("\n %d", head->data);
return head;
}
(3)单链表的输出过程有以下几步
1) 找到表头;
2) 若是非空表,输出节点的值成员,是空表则退出;
3 ) 跟踪链表的增长,即找到下一个节点的地址;
4) 转到2 ).
代码如下:
void print(node *head)
{
node *p;
int n = length(head);
printf("\n These %drecords are :\n", n);
p = head;
if (head != NULL)
{
while (p != NULL)
{
printf("\n%d ", p->data);
p =p->next;
}
}
}
(二)单链表的插入
单链表的插入,如下图所示
如果插入节点在头节点以前,则p0的next指向p1,头节点指向p0,如下图所示。
如果插入中间节点,如下图所示。
则先让p2的next指向p0,再让p0指向p1,如下图所示。
如果插入尾结点,如下图所示。
则先让p1的next指向p0,再让p0指向空,如下图所示
完整代码如下:
//单链表插入
node *insert(node *head, int num)
{
node *p0, *p1, *p2=NULL;
p1 = head;
p0 =(node*)malloc(sizeof(node));
p0->data = num;
//找到合适的插入元素位置
while (p0->data >p1->data&&p1->next != NULL)
{
p2 = p1;
p1 = p1->next;
}
if (p0->data <= p1->data)
{
//在头节点前插入元素
if (p1 == head)
{
p0->next =p1;
head = p0;
}
//在中间节点插入元素
else
{
p2->next =p0;
p0->next =p1;
}
}
//尾结点插入元素
else
{
p1->next = p0;
p0->next = NULL;
}
return head;
}
(三)单链表的删除
如果删除的是头节点,如下图所示
则把head指针指向头节点的下一个节点,同时free p1,如下图所示。
如果删除的中间节点,如下图所示
则用p2的next指向p1的next的同时,free p1,如下图所示
代码如下:
//单链表删除
node *del(node *head, int num)
{
node *p1, *p2=NULL;
p1 = head;
//找到删除节点或遍历完链表未找到时退出循环
while (num !=p1->data&&p1->next != NULL)
{
p2 = p1;
p1 = p1->next;
}
if (num == p1->data)
{
//删除的是头节点
if (p1 == head)
{
head =p1->next;
free(p1);
}
//删除中间节点,将前节点后继指向该节点后继
else
p2->next =p1->next;
}
else
{
printf("%d cann'tbeen found in list", num);
}
return head;
}
(四)单链表排序
此处给予简单的基于冒泡排序的链表排序代码,如下
//单链表排序,冒泡方法
node *sort(node *head)
{
node *p;
int n = length(head);
int temp = 0;
if (head == NULL ||head->next == NULL)
return head;
p = head;
for (int i = 1; i < n;i++)
{
p = head;
for (int j = 0; j <n - i; j++)
{
if(p->data>p->next->data)
{
temp =p->data;
p->data= p->next->data;
p->next->data= temp;
}
p =p->next;
}
}
return head;
}
(五)单链表逆置(时间复杂度为O(n))
解析:单链表模型如下。
进行单链表逆置,首先要让p2的next指向p1,如下图所示。
再由p1指向p2,p2指向p3,如下图所示
代码如下:
//时间复杂度为O(n) 的单链表逆置
node *reverse(node *head)
{
node *p1, *p2, *p3;
if (head == NULL ||head->next == NULL)
return head;
p1 = head;
p2 = p1->next;
while (p2)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
head->next = NULL;
head = p1;
return head;
}