天天看点

单链表的选择排序

思想:维持一个输入的链表(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();
}
           

运行:

单链表的选择排序

继续阅读