本文转载自http://blog.csdn.net/zhipi/article/details/4425533
前日遇到一个问题:对双向链表按关键字域进行排序。
在网上找了一下,都只一种算法,而且是对无头结点的双向链表的排序,对于指针的交换,分了8种情况,我觉得很烦。于是自己想了一下,写了个带头结点的双向链表的选择排序算法,指针的交换浓缩到4种情况,而且自认为选择排序函数中的结构很巧妙,于是贴出来与人分享!
#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define ERROR 0
#include "stdlib.h"
#include <iostream>
using namespace std;
typedef int Status;
typedef struct{ //定义数据域
int no; //关键字域——学号
char name[13]; //姓名
}ElemType;
typedef struct DuLNode{ //定义结点类型
ElemType data; //数据域
struct DuLNode * prior; //前驱指针
struct DuLNode * next; //后继指针
}DuLNode, * DuLinkList;
Status Create(DuLinkList &H) //创建双向链表
{
H=(DuLNode *)malloc(sizeof(DuLNode));
if(!H)
return OVERFLOW;
H->prior=NULL;
H->next=NULL;
return OK;
}
void Insert(DuLinkList &H,int n=1) //利用尾插法向双向链表中插入1个(默认)或n个(用户指定)结点
{
DuLNode *t;
if(H->next==NULL) //查找尾结点
t=H;
else
{
t=H->next;
while(t->next!=NULL)
t=t->next;
}
cout<<"输入"<<endl;
for(int i=0;i<n;i++)
{
DuLNode *p=0;
p=(DuLNode *)malloc(sizeof(DuLNode));
cin>>p->data.no>>p->data.name;
t->next=p;
p->prior=t;
p->next=NULL;
t=t->next;
}
}
void Output(DuLinkList H) //输出双向链表
{
DuLNode *p;
p=H->next;
cout<<"学号"<<"/t"<<"姓名"<<endl;
while(p!=NULL)
{
cout<<p->data.no<<"/t"<<p->data.name<<endl;
p=p->next;
}
}
void swap(DuLinkList &H,DuLNode *p,DuLNode *t) //p,t结点有序,p为前结点,t为后结点
{
DuLNode *temp;
if(t->next==NULL) //t结点是否为尾结点
{
if(p->next==t) //p,t结点是否相邻
{
//与尾结点相邻的交换代
t->next=p;
t->prior=p->prior;
p->next=NULL;
p->prior->next=t;
p->prior=t;
}
else
{
//与尾结点不相邻的交换代
t->next=p->next;
t->prior->next=p;
temp=t->prior;
t->prior=p->prior;
p->next->prior=t;
p->next=NULL;
p->prior->next=t;
p->prior=temp;
}
}
else
{
if(p->next==t) //p,t结点是否相邻
{
//相邻的交换代
t->next->prior=p;
temp=t->next;
t->next=p;
t->prior=p->prior;
p->next=temp;
p->prior->next=t;
p->prior=t;
}
else
{
//不相邻的交换代
t->next->prior=p;
temp=t->next;
t->next=p->next;
p->next->prior=t;
p->next=temp;
t->prior->next=p;
temp=t->prior;
t->prior=p->prior;
p->prior->next=t;
p->prior=temp;
}
}
}
void Sort(DuLinkList &H) //选择排序算法
{
DuLNode *i,*j,*k;
if(!H->next) //双向链表为空则返回
return;
for(i=H->next;i->next!=NULL;i=k->next) //i=k->next是关键,k记录了双向链表交换指针后的下一个i的值(地址)
{
for(j=i->next,k=i;j!=NULL;j=j->next)
if(k->data.no>j->data.no)
k=j;
if(k!=i)
swap(H,i,k);
}
}
void main()
{
DuLinkList H;
Create(H);
Insert(H,4);
Output(H);
Sort(H);
Output(H);
}