带头节点单链表排序
本代码是带头节点单链表排序的其中一种方法,即直接插入排序,通过将整个单链表断成两部分,一部分为有序单链表,后一部分为无序单链表。通过每次将无序单链表的第一个节点的值直接插入到前面的有序单链表的指定位置。来实现单链表的排序。
头文件 slnklist.h
#include <stdio.h>
#include <stdlib.h>
/**************************************/
/* 链表实现的头文件,文件名slnklist.h */
/**************************************/
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
/******************************************/
/*函数名称:creatbystack() */
/*函数功能:头插法建立带头结点的单链表 */
/******************************************/
linklist creatbystack()
{
linklist head,s;
datatype x;
head=(linklist)malloc(sizeof(node));
head->next=NULL;
//printf("请输入整数序列(空格分开,以0结束):\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
s->next=head->next;
head->next=s;
scanf("%d",&x);
}
return head;
}
/****************************************/
/*函数名称:creatbyqueue() */
/*函数功能:尾插法建立带头结点的单链表 */
/****************************************/
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head=r=(linklist)malloc(sizeof(node));
head->next=NULL;
//printf("请输入整数序列(空格分开,以0结束):\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return head;
}
/************************************/
/*函数名称:print() */
/*函数功能:输出带头结点的单链表 */
/************************************/
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
while(p)
{
printf("%7d",p->info);
i++;
if(i%10==0) printf("\n");
p=p->next;
}
printf("\n");
}
/************************************/
/*函数名称:delList() */
/*函数功能:释放带头结点的单链表 */
/************************************/
void delList(linklist head)
{
linklist p=head;
while(p)
{
head=p->next;
free(p);
p=head;
}
}
头文件主要存储的是单链表的几个基本操作函数
核心程序
void sort(linklist head)
{
linklist p,q,r,pre;
p=head->next;//p指向第一个节点
q=p->next;//q要指向p的后继节点,保证在后面断开之后能够找到后续的单链表中元素的位置
p->next=NULL;//断开单链表,将单链表分成前部分为有序单链表,后部分为无需单链表
p=q;//p往后开始找到无序单链表的第一个值
while(p!=NULL)
{
q=p->next;//q还是指向p的后继,保证不丢失
r=head;//r的作用是遍历有序单链表找到让值插入的位置
while(r->next!=NULL&&r->next->info<p->info)//因为r所遍历的是有序的,所以只要找到了一个位置,令r的后继节点的值大于p->info,就把p插在r和r->next中间
{
r=r->next;//遍历
}
pre=r;//借助pre进行插入操作
p->next=pre->next;//插入操作
pre->next=p;
p=q;//因为已经将无序单链表的第一个值插入到有序单链表中,所以p往后移一位,这里也可以写成p=p->next
}
}
int main()
{
linklist head;
head=creatbyqueue(); /*尾插法建立带头结点的单链表*/
print(head); /*输出单链表head*/
sort(head); /*排序*/
print(head);
delList(head);
return 0;
}
单链表可以借助画图来理解
单链表其实我是不太熟悉的(菜鸟一枚),若有错误,请多多指教,本代码的方法是直接插入排序,单链表排序还可以通过冒泡排序的方式,或者将单链表的元素都放入数组中,通过数组的排序(应该已经学完),在将值插回到单链表中。