冒泡排序,在每次遍历的每个链表数据中找出数据最小或最大的节点
和原始链表数据的头节点交换, 交换的过程中要用到,待交换头节点和最大或最小节点的
前驱节点。 还要注意带头节点第一个冒泡上来的数和头节点的交换。
还要注意头节点就是最小节点的前驱节点的情况。
//
LinkListSort.cpp : 定义控制台应用程序的入口点。
//
#include " stdafx.h "
#include " stdlib.h "
typedef int DataType;
typedef struct node
{
DataType data;
struct node * next;
}LinkNode;
LinkNode * Insert(DataType data,LinkNode * h);
// 没有带头节点
LinkNode * CreateLinkList( int num)
{
LinkNode * h;
h = (LinkNode * )malloc( sizeof (LinkNode));
h -> next = NULL;
return h;
}
/*
向链表中出入数据
参数为链表的头节点,和待插入的节点的数据
*/
LinkNode * Insert(DataType data,LinkNode * h)
{
LinkNode * p = h, * pr;
LinkNode * q;
q = (LinkNode * )malloc( sizeof (LinkNode));
q -> data = data;
q -> next = h -> next;
h -> next = q;
return h;
}
/*
显示链表的数据
*/
LinkNode * ShowLinkList(LinkNode * h)
{
LinkNode * p = h;
printf( " \n " );
while (p != NULL)
{
printf( " %d- " ,p -> data);
p = p -> next;
}
return h;
}
// 链表实现冒泡排序- 从小到大
LinkNode * SortLinkList(LinkNode * h)
{
LinkNode * hh = h, * pr, * p, * pp, * ppr, * temp, * ph;
DataType min;
int flag = 1 ; // 是否是头一次的节点
ph = h;
while (h != NULL)
{
min = h -> data;
p = h;
pr = p;
ppr = pr;
pp = p;
/*
排好顺序的链表为头节点hh开头,每次都从h节点开头的
链表冒泡出数值最小的节点,接到hh链表开头的链表尾部。
*/
// 开始冒泡
while (p != NULL)
{
if (p -> data < min) // 找出 节点值数据最小的节点
{
ppr = pr; // 最小节点的父节点
pp = p; // 最小节点
min = p -> data; // 节点的最小数值
}
pr = p;
p = p -> next;
}
/*
找到h节点之后,数值最小的节点, pp代表该最小节点
ppr为pp的先驱节点
*/
if (ppr == pp)
{
h = pp;
ph -> next = h;
if (flag == 1 ) // 在还未建立头节点时,先建立头节点,hh代表该头节点
{
hh = h;flag = 0 ; // 头节点h之前的节点都是已经按从小到达的顺序排好顺序的节点,
}
} else
{
/*
如果最小节点不是头节点p的后驱节点的话
就把头节点h和最小数值节点兑换
*/
if (h != ppr)
{
/*
交换节点 h和pp
用到两个的节点的先驱节点ph和ppr
*/
temp = h -> next;
ppr -> next = h;
h -> next = pp -> next;
pp -> next = temp;
h = pp;
if (flag == 1 ){hh = h;flag = 0 ;}
else
{
ph -> next = h;
}
} else
{ /*
如果最小节点p是头节点h的后驱节点的话
调换两个节点
*/
h -> next = pp -> next;
pp -> next = h;
h = pp;
if (flag == 1 ){hh = h;flag = 0 ;}
else {
ph -> next = pp;
}
}
}
ph = h; // ph为头节点h移动时的先驱节点
h = h -> next;
}
return hh;
}
int _tmain( int argc, _TCHAR * argv[])
{
LinkNode * h;
h = CreateLinkList( 10 );
h -> data = 3 ;
Insert( 1 ,h);
Insert( 2 ,h);
Insert( 8 ,h);
Insert( 3 ,h);
Insert( 4 ,h);
Insert( 5 ,h);
Insert( 8 ,h);
Insert( 5 ,h);
Insert( 45 ,h);
Insert( 40 ,h);
Insert( 5 ,h);
ShowLinkList(h);
h = SortLinkList(h);
ShowLinkList(h);
return 0 ;
}
//
#include " stdafx.h "
#include " stdlib.h "
typedef int DataType;
typedef struct node
{
DataType data;
struct node * next;
}LinkNode;
LinkNode * Insert(DataType data,LinkNode * h);
// 没有带头节点
LinkNode * CreateLinkList( int num)
{
LinkNode * h;
h = (LinkNode * )malloc( sizeof (LinkNode));
h -> next = NULL;
return h;
}
/*
向链表中出入数据
参数为链表的头节点,和待插入的节点的数据
*/
LinkNode * Insert(DataType data,LinkNode * h)
{
LinkNode * p = h, * pr;
LinkNode * q;
q = (LinkNode * )malloc( sizeof (LinkNode));
q -> data = data;
q -> next = h -> next;
h -> next = q;
return h;
}
/*
显示链表的数据
*/
LinkNode * ShowLinkList(LinkNode * h)
{
LinkNode * p = h;
printf( " \n " );
while (p != NULL)
{
printf( " %d- " ,p -> data);
p = p -> next;
}
return h;
}
// 链表实现冒泡排序- 从小到大
LinkNode * SortLinkList(LinkNode * h)
{
LinkNode * hh = h, * pr, * p, * pp, * ppr, * temp, * ph;
DataType min;
int flag = 1 ; // 是否是头一次的节点
ph = h;
while (h != NULL)
{
min = h -> data;
p = h;
pr = p;
ppr = pr;
pp = p;
/*
排好顺序的链表为头节点hh开头,每次都从h节点开头的
链表冒泡出数值最小的节点,接到hh链表开头的链表尾部。
*/
// 开始冒泡
while (p != NULL)
{
if (p -> data < min) // 找出 节点值数据最小的节点
{
ppr = pr; // 最小节点的父节点
pp = p; // 最小节点
min = p -> data; // 节点的最小数值
}
pr = p;
p = p -> next;
}
/*
找到h节点之后,数值最小的节点, pp代表该最小节点
ppr为pp的先驱节点
*/
if (ppr == pp)
{
h = pp;
ph -> next = h;
if (flag == 1 ) // 在还未建立头节点时,先建立头节点,hh代表该头节点
{
hh = h;flag = 0 ; // 头节点h之前的节点都是已经按从小到达的顺序排好顺序的节点,
}
} else
{
/*
如果最小节点不是头节点p的后驱节点的话
就把头节点h和最小数值节点兑换
*/
if (h != ppr)
{
/*
交换节点 h和pp
用到两个的节点的先驱节点ph和ppr
*/
temp = h -> next;
ppr -> next = h;
h -> next = pp -> next;
pp -> next = temp;
h = pp;
if (flag == 1 ){hh = h;flag = 0 ;}
else
{
ph -> next = h;
}
} else
{ /*
如果最小节点p是头节点h的后驱节点的话
调换两个节点
*/
h -> next = pp -> next;
pp -> next = h;
h = pp;
if (flag == 1 ){hh = h;flag = 0 ;}
else {
ph -> next = pp;
}
}
}
ph = h; // ph为头节点h移动时的先驱节点
h = h -> next;
}
return hh;
}
int _tmain( int argc, _TCHAR * argv[])
{
LinkNode * h;
h = CreateLinkList( 10 );
h -> data = 3 ;
Insert( 1 ,h);
Insert( 2 ,h);
Insert( 8 ,h);
Insert( 3 ,h);
Insert( 4 ,h);
Insert( 5 ,h);
Insert( 8 ,h);
Insert( 5 ,h);
Insert( 45 ,h);
Insert( 40 ,h);
Insert( 5 ,h);
ShowLinkList(h);
h = SortLinkList(h);
ShowLinkList(h);
return 0 ;
}