双向链表的选择排序算法

本文转载自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);
}



  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值