单链表进行排序-通过节点交换,不通过值交换
2014-04-20 20:36
316 查看
原来我一直都不会对链表进行排序,呵呵,比较菜。今天下了很大的功夫学习对链表的排序,和大家分享一下!
对链表的排序主要有两种方法:
一:只交换节点中的元素,不改变链表的顺序。
二:直接交换节点,不改变节点中的元素。
其中交换节点是最麻烦的,稍不注意就会出错!而交换节点中的元素还是比较简单的。用几个swap( )就可以了。
单链表的冒泡排序法:
// powered by sunkehappy QQ 675313675
// 用冒泡排序法对链表中的元素进行按照非降序排列
#include <stdio.h>
#include <conio.h> // getch()
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( LinkList *head, int num )
{
int i, data;
LinkList p;
// 建立链表
printf("请输入节点中的元素(整数):\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
// 读取数据并存放在节点中
scanf("%d",&data);
p->data = data;
// 建立链表,并插入到head后
p->next = ( *head )->next;
( *head )->next = p;
}
return ( *head )->next;
}// CreateList
// 用冒泡法对链表中的节点排序
void BubbleSort( LinkList head )
{
LinkList p, prep, temp, tail;
tail = NULL;
// 算法的核心部分
while( head->next != tail ){
prep = head;
p = head->next;
while( p->next != tail ){
if( p->data > p->next->data ){
temp = p->next;
prep->next = p->next;
p->next = p->next->next;
prep->next->next = p;
p = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
tail = p;
}// 第一个while
}// BubbleSort
void Print( LinkList head )
{
while( head != NULL ){
printf("%d ",head->data);
head = head->next;
}
}
int main( void )
{
int num;
LinkList head;
// prep为指向p之前的节点的指针
printf("请输出要建立的节点的个数:\n");
scanf("%d",&num);
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立长度为num的链表
head->next = CreateLink( &head, num );
BubbleSort( head );
printf("经过排序后的数据为:\n");
Print( head->next );
getch();
}
我在刚开始的时候也是没能够自己想出来,怎么弄都弄不好。在网上搜了一些,终于看懂了。但是他们写的基本没有注释,可读性很差。所以我就自己写了一个。
单链表的冒泡排序法的难点在于如何实现双重循环,好好理解其中那个tail的用法;以及以及如何交换节点,注意temp的用法。
下面是单链表通过交换数据的排序方法(双循环有点像冒泡排序法):
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( int num )
{
int i;
LinkList p, head;
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立头结点以后的节点
printf("请输入节点中的数据:\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
p->next = head->next;
head->next = p;
scanf("%d", &p->data );
}
return head;
}// CreateLink
int ListLength( LinkList head )
{
int len = 0;
while( head != NULL ){
++ len;
head = head->next;
}
return len;
}
void SortLink( LinkList *head )
{
int i, j, temp, len ;
LinkList prep,p;
len = ListLength( *head );
for( i = 0; i < len; i++ ){
prep = ( *head );
p = ( *head )->next;
for( j = 0; j < len -1 - i; j++ ){
if( prep->data > p->data ){
temp = prep->data;
prep->data = p->data;
p->data = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
}// while
}// SortLink
// 输出链表中的数据
void PrintLink( LinkList head )
{
printf("排序后的链表中的数据为:\n");
while( head != NULL ){
printf("%d ", head->data );
head = head->next;
}
}
int main( void )
{
int num;
LinkList head ;
printf("请输入要建立的节点数:\n");
scanf("%d", &num );
// 建立有num个节点的链表
head = CreateLink( num );
SortLink( &head->next );
PrintLink( head->next );
getch();
return 0;
}
对链表的排序主要有两种方法:
一:只交换节点中的元素,不改变链表的顺序。
二:直接交换节点,不改变节点中的元素。
其中交换节点是最麻烦的,稍不注意就会出错!而交换节点中的元素还是比较简单的。用几个swap( )就可以了。
单链表的冒泡排序法:
// powered by sunkehappy QQ 675313675
// 用冒泡排序法对链表中的元素进行按照非降序排列
#include <stdio.h>
#include <conio.h> // getch()
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( LinkList *head, int num )
{
int i, data;
LinkList p;
// 建立链表
printf("请输入节点中的元素(整数):\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
// 读取数据并存放在节点中
scanf("%d",&data);
p->data = data;
// 建立链表,并插入到head后
p->next = ( *head )->next;
( *head )->next = p;
}
return ( *head )->next;
}// CreateList
// 用冒泡法对链表中的节点排序
void BubbleSort( LinkList head )
{
LinkList p, prep, temp, tail;
tail = NULL;
// 算法的核心部分
while( head->next != tail ){
prep = head;
p = head->next;
while( p->next != tail ){
if( p->data > p->next->data ){
temp = p->next;
prep->next = p->next;
p->next = p->next->next;
prep->next->next = p;
p = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
tail = p;
}// 第一个while
}// BubbleSort
void Print( LinkList head )
{
while( head != NULL ){
printf("%d ",head->data);
head = head->next;
}
}
int main( void )
{
int num;
LinkList head;
// prep为指向p之前的节点的指针
printf("请输出要建立的节点的个数:\n");
scanf("%d",&num);
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立长度为num的链表
head->next = CreateLink( &head, num );
BubbleSort( head );
printf("经过排序后的数据为:\n");
Print( head->next );
getch();
}
我在刚开始的时候也是没能够自己想出来,怎么弄都弄不好。在网上搜了一些,终于看懂了。但是他们写的基本没有注释,可读性很差。所以我就自己写了一个。
单链表的冒泡排序法的难点在于如何实现双重循环,好好理解其中那个tail的用法;以及以及如何交换节点,注意temp的用法。
下面是单链表通过交换数据的排序方法(双循环有点像冒泡排序法):
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( int num )
{
int i;
LinkList p, head;
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立头结点以后的节点
printf("请输入节点中的数据:\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
p->next = head->next;
head->next = p;
scanf("%d", &p->data );
}
return head;
}// CreateLink
int ListLength( LinkList head )
{
int len = 0;
while( head != NULL ){
++ len;
head = head->next;
}
return len;
}
void SortLink( LinkList *head )
{
int i, j, temp, len ;
LinkList prep,p;
len = ListLength( *head );
for( i = 0; i < len; i++ ){
prep = ( *head );
p = ( *head )->next;
for( j = 0; j < len -1 - i; j++ ){
if( prep->data > p->data ){
temp = prep->data;
prep->data = p->data;
p->data = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
}// while
}// SortLink
// 输出链表中的数据
void PrintLink( LinkList head )
{
printf("排序后的链表中的数据为:\n");
while( head != NULL ){
printf("%d ", head->data );
head = head->next;
}
}
int main( void )
{
int num;
LinkList head ;
printf("请输入要建立的节点数:\n");
scanf("%d", &num );
// 建立有num个节点的链表
head = CreateLink( num );
SortLink( &head->next );
PrintLink( head->next );
getch();
return 0;
}
相关文章推荐
- 采用选择排序法对链表进行排序,注意交换操作中不是对链表里某一节点里的某一元素进行交换,而是对两节点指针的交换
- 长度为N的数组乱序存放着0带N-1.现在只能进行0与其他数的swap操作,请设计并实现排序,必须通过交换实现排序。
- 长度为N的数组乱序存放着0带N-1.现在只能进行0与其他数的swap操作,请设计并实现排序,必须通过交换实现排序。
- 对一个存储学生信息的单向链表,按照学号升序对链表进行排序,每个节点包含了一个学生ID
- 单链表节点插入并进行排序
- 链表的带参数排序,可以通过姓名、成绩进行升序或降序操作
- 链表排序交换节点为什么还得单独交换next指针?
- 单链表排序交换节点算法
- c - 对数组进行排序(通过指针的指针)
- 7-6 冒泡法排序(20 分) 将N个整数按从小到大排序的冒泡排序法是这样工作的:从头到尾比较相邻两个元素,如果前面的元素大于其紧随的后面元素,则交换它们。通过一遍扫描,则最后一个元素必定是最大的元素
- List排序 通过Comparable接口进行排序
- 交换任意两个元素进行排序进行的最小交换次数
- 通过js去对表格的列,根据其内容进行排序(升序或者降序)
- java对List<Object>型列表进行排序(通过内部类对compare(**)方法重写)
- PHP函数Ksort()通过关键字对数组进行排序的具体方式介绍
- 单链表任意交换两节点
- 55. 链表节点排序
- 删除排序链表中重复的节点 递归方式
- 单链表中进行直接插入排序(有头节点)
- 链表的冒泡排序(节点交换法)