单链表的选择排序

本文介绍了如何使用选择排序算法对单链表进行排序。通过维护一个输入链表和一个输出链表,遍历输入链表找到最小(或最大)元素,移除并插入到输出链表头部,直至输入链表为空。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思想:维持一个输入的链表(head指向这个链表),和一个输出链表(out指向这个链表),当输入链表非空时时,扫描这个链表,找出表中剩余节点中的最大节点,然后从输入表中去除这个节点,并把它插入到输出表的前面。

单链表的节点类型定义如下:

typedef struct Node
{
	int item;
	struct Node *next;
}ListNode,*List;

选择排序算法如下:

/****************************************链表的选择排序操作(从小到大)*********************************************/
List FindMaxPreNode(List head) /*返回当前链表中最大值节点的上一个结点(直接前驱节点)*/
{
	ListNode *p=head;
	ListNode *maxnode=head;//开始时假定头结点即为最大值节点
	ListNode *prenode=NULL;
	while(p!=NULL)//找到当前最大值结点(迭代)
	{
		if(p->item >= maxnode->item)
		{

			maxnode=p;
		}
		p=p->next;
	}

    /*找最大值结点的前驱prenode,如果第一个结点就是最大节点,那么prenode==NULL;*/
    for(p=head;p!=NULL;prenode=p,p=p->next)
	{
		if(p==maxnode)
			break;
	}
	return prenode;
}
List List_SelectionSort(List head)  /*j进行选择排序*/
{
	assert(head!=NULL);
	ListNode *maxprenode;//当前最大值节点的直接前驱结点的指针
	ListNode *t;
	List out=NULL;//排序后的链表头指针
	while(head!=NULL)
	{
		maxprenode=FindMaxPreNode(head);
		if(maxprenode==NULL)//最大值节点的前驱节点为空,即该节点是链表第一个结点(头结点)时
		{
			t=head;
			head=t->next;
		}
		else//如果最大值节点不是头结点
		{
		    t=maxprenode->next;
		    maxprenode->next=t->next;
		}
		t->next=out;//将当前找到的最大节点插入到输出链表out的头部(即头插法)
		out=t;
	}
	head=out;//将链表out的头指针赋给head,这样以head为头指针的链表就排好序了。
	return head;
}
/*******************************************************************************************/

下面是完整代码运行通过对于其中链表中的其他操作也可以参考复习

/***************************************************************************
 *name:jae chia                                                            *
 *date:2014.8.30                                                           *
 *version: 1.0                                                             *
 **************************************************************************/
#include<iostream>
#include<cassert>
using namespace std;

typedef struct Node
{
	int item;
	struct Node *next;
}ListNode,*List;
List InsertNodeToTail(List head,int data)//尾端插入
{
	ListNode *newnode=(List)malloc(sizeof(ListNode));//创建新节点
	assert(newnode);
	newnode->item=data;
	newnode->next=NULL;

	if(head==NULL)
		head=newnode;
	else
	{
		ListNode *p=head;
	    while(p->next!=NULL)
		{
			p=p->next;
		}
		p->next=newnode;
		newnode->next=NULL;
	}
	return head;
}
List InsertNodeToFront(List head,int data)//头部插入
{
	ListNode *newnode=(List)malloc(sizeof(ListNode));//创建新节点
	assert(newnode);
	newnode->item=data;
	newnode->next=NULL;

	if(head==NULL)
		head=newnode;
	else
	{
		newnode->next=head;
	    head=newnode;
	}
	return head;
}
/****************************************链表的选择排序操作(从小到大)*********************************************/
List FindMaxPreNode(List head) /*返回当前链表中最大值节点的上一个结点(直接前驱节点)*/
{
	ListNode *p=head;
	ListNode *maxnode=head;//开始时假定头结点即为最大值节点
	ListNode *prenode=NULL;
	while(p!=NULL)//找到当前最大值结点(迭代)
	{
		if(p->item >= maxnode->item)
		{

			maxnode=p;
		}
		p=p->next;
	}

    /*找最大值结点的前驱prenode,如果第一个结点就是最大节点,那么prenode==NULL;*/
    for(p=head;p!=NULL;prenode=p,p=p->next)
	{
		if(p==maxnode)
			break;
	}
	return prenode;
}
List List_SelectionSort(List head)  /*j进行选择排序*/
{
	assert(head!=NULL);
	ListNode *maxprenode;//当前最大值节点的直接前驱结点的指针
	ListNode *t;
	List out=NULL;//排序后的链表头指针
	while(head!=NULL)
	{
		maxprenode=FindMaxPreNode(head);
		if(maxprenode==NULL)//最大值节点的前驱节点为空,即该节点是链表第一个结点(头结点)时
		{
			t=head;
			head=t->next;
		}
		else//如果最大值节点不是头结点
		{
		    t=maxprenode->next;
		    maxprenode->next=t->next;
		}
		t->next=out;//将当前找到的最大节点插入到输出链表out的头部(即头插法)
		out=t;
	}
	head=out;//将链表out的头指针赋给head,这样以head为头指针的链表就排好序了。
	return head;
}
/*******************************************************************************************/
bool FindNode(List head,int data)//查找链表中含有某元素的节点是否存在
{
	if(head==NULL)
	{
		cout<<"the Dlist is NULL"<<endl;
		return false;
	}
	ListNode *p=head;
	while(p!=NULL)
	{
		if(p->item==data)
			return true;
		p=p->next;
	}
	return false;
}

List DeleteNode(List head,int data)//删除节点
{
	assert(head);
	ListNode *p=head;
	ListNode *pre=NULL;
	for(;p!=NULL;pre=p,p=p->next)
	{
		if(p->item==data)
			break;
	}
	if(p==NULL)
	{
		cout<<"the  node you want to delete not exist!"<<endl;
		return head;
	}
	if(pre==NULL)
	{
		ListNode *tmp=head;
		head=head->next;
		free(tmp);
	}
	else
	{
		pre->next=p->next;
		free(p);
	}
	return head;  
}
void PrintList(List head)//打印
{
	if(head==NULL)
	{
		cout<<"the list is NULL"<<endl;
		return ;
	}
	ListNode *p=head;
	while(p!=NULL)
	{
		cout<<p->item<<" ";
		p=p->next;
	}
	cout<<endl<<endl;
}
void DestroyList(List head)//销毁双向链表
{
	ListNode *p=head;
	while(p!=NULL)
	{
		ListNode *tmp=p;
		p=p->next;
		free(tmp);
	}
}

void Test()
{
	List head=NULL;
	head=InsertNodeToTail(head,5);
	head=InsertNodeToTail(head,3);
	head=InsertNodeToFront(head,7);
	head=InsertNodeToFront(head,10);
	head=InsertNodeToTail(head,4);
	head=InsertNodeToFront(head,1);
	head=InsertNodeToTail(head,2);
	//head=DeleteNode(head,4);
	cout<<"初始化后的链表:"<<endl;;
	PrintList(head);
	
	head=List_SelectionSort(head);
	cout<<"排序后的链表  :"<<endl;;
	PrintList(head);

	DestroyList(head);
}
int main(void)
{
	Test();
}

运行:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值