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