前日遇到一个问题:对双向链表按关键字域进行排序。
在网上找了一下,都只一种算法,而且是对无头结点的双向链表的排序,对于指针的交换,分了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); }
很久以前(大约是2007年)发的博文了,现在从新浪博客转过来。