数据结构_内部排序_希尔排序_快速排序_堆排序_归并排序_地址排序

数据结构_内部排序_希尔排序_快速排序_堆排序_归并排序_地址排序

几种典型的排序算法,算法排序对象都为顺序表,还有一个基数排序的算法由于采用不同的存储结构就没有加在这个文件中,稍后会贴出其代码。

sort.h

#include<iostream>
#include<ctime>
using namespace std;

typedef int ElemType;

#define LISTLEN 100

typedef struct SqList //顺序表
{
	ElemType *elem;
	int length;
	int listsize;
} SqList;

void InitList(SqList &L) //顺序表初始化
{
	L.elem = new ElemType[LISTLEN + 1];
	L.length = 0;
	L.listsize = LISTLEN;
}

void InitList(SqList &L, int len) //顺序表函数
{
	L.elem = new ElemType[len + 1];
	L.length = 0;
	L.listsize = len;
}

void GetRandomNum(SqList &L) //获取随机数
{
	srand((unsigned) time(NULL));
	for (int i = 0; i < L.listsize; i++)
		L.elem[i] = rand() % 100;
	L.length = L.listsize;
}

void GetRandomNum(SqList &L, int randombase) //获取随机数
{
	srand((unsigned) time(NULL));
	for (int i = 0; i < L.listsize; i++)
		L.elem[i] = rand() % randombase;
	L.length = L.listsize;
}

void PrintList(SqList &L) //打印顺序表元素
{
	for (int i = 0; i < L.length; i++)
		cout << L.elem[i] << " ";
	cout << endl;
}

/////////////////////////////////////////////////////////////希尔排序

void ShellInsert(SqList &L, int dk) //希尔插入dk表示增量
{
	ElemType temp;
	int j;
	for (int i = dk; i < L.length; i++)
	{
		if (L.elem[i] < L.elem[i - dk])
		{
			temp = L.elem[i];
			j = i - dk;
			while (j >= 0 && temp < L.elem[j])
			{
				L.elem[j + dk] = L.elem[j];
				L.elem[j] = temp;
				j -= dk;
			}
		}
	}
}

void ShellSort(SqList &L, int dlta[], int t) //希尔排序
{
	for (int k = 0; k < t; k++)
	{
		ShellInsert(L, dlta[k]);
	}
}

/////////////////////////////////////////////////////////////快速排序

int Partition(SqList &L, int low, int high)
{
	ElemType temp;
	temp = L.elem[(low + high) / 2];
	while (low < high)
	{
		while (low < high && L.elem[high] >= temp)
			high--;
		L.elem[low] = L.elem[high];
		while (low < high && L.elem[low] <= temp)
			low++;
		L.elem[high] = L.elem[low];
	}
	L.elem[low] = temp;
	return low;
}

void QuickSort(SqList &L, int low, int high)
{
	if (low < high)
	{
		int pivotkey = Partition(L, low, high);
		QuickSort(L, low, pivotkey - 1);
		QuickSort(L, pivotkey + 1, high);
	}
}

void Qsort(SqList &L)
{
	QuickSort(L, 0, L.length - 1);
}

/////////////////////////////////////////////////////////////堆排序

typedef SqList HeapType;

/////////////////////////////////////////////////////////////
//您可以无视下面两个函数,也可以用这两个函数来耻笑在下,具体原因不解释...
void ListAdjust(HeapType &H) //调整顺序表元素位置使其所有元素后移一位
{
	for (int i = H.length - 1; i >= 0; i--)
		H.elem[i + 1] = H.elem[i];
}

void ListReAdjust(HeapType &H) //调整顺序表元素位置使其所有元素前移一位
{
	for (int i = 0; i < H.length - 1; i++)
		H.elem[i] = H.elem[i + 1];
}
///////////////////////////////////////////////////////////////

void HeapAdjust(HeapType &H, int s, int m)
//已知H.elem[s...m]除H.elem[s]外均满足堆的定义
//本函数调整H.elem[s]的关键字使H.[s...m]成为一个大顶堆
{
	ElemType temp = H.elem[s]; //保存顶元素
	for (int i = 2 * s; i <= m; i *= 2) //遍历
	{
		if (i < m && (H.elem[i] < H.elem[i + 1]))
			//如果左子树关键字小于右子树关键字
			i++; //“指针”指向其右子树
		if (temp >= H.elem[i]) //如果满足定义直接跳出
			break;
		H.elem[s] = H.elem[i]; //更新关键字次序
		s = i;
	}
	H.elem[s] = temp;
}

void HeapSort(HeapType &H)
{
	ListAdjust(H); //调整顺序表使其所有元素后移
	ElemType temp;
	for (int i = H.length / 2; i > 0; i--) //建立大顶堆
		HeapAdjust(H, i, H.length);
	for (int i = H.length; i > 1; i--) //将堆顶记录和未经排序的最后一个记录交换
	{
		temp = H.elem[i];
		H.elem[i] = H.elem[1];
		H.elem[1] = temp;
		HeapAdjust(H, 1, i - 1); //重新将H.elem[1...i-1]调整为大顶堆
	}
	ListReAdjust(H); //调整顺序表元素位置使其所有元素前移一位
}

///////////////////////////////////////////////////////////////归并排序
/*
 这段程序调试了N久
 老是有一些莫名其妙的错误
 还好最终调试通了
 没有采取数据结构书上的方法
 */
void Merge(ElemType *L, ElemType *T, int left, int mid, int right)
//合并算法将T[left...mid],T[mid+1...right] 有序合并到L[left...right]
{
	for (int i = left; i <= right; i++) //复制元素
		T[i] = L[i];
	int i = left, j = mid + 1, k = left;
	//合并
	while (i <= mid && j <= right)
	{
		if (T[i] <= T[j])
			L[k++] = T[i++];
		else
			L[k++] = T[j++];
	}
	while (i <= mid)
		L[k++] = T[i++];
	while (j <= right)
		L[k++] = T[j++];
}

void MSort(ElemType *L, ElemType *T, int left, int right)
//将T[left...right]有序归并到L[left..right]
{
	if (left < right)
	{
		int mid = (left + right) / 2; //平分
		MSort(L, T, left, mid); //左半部分
		MSort(L, T, mid + 1, right); //右半部分
		Merge(L, T, left, mid, right); //有序归并
	}
}

void MergeSort(SqList &L)
{
	ElemType t[LISTLEN];
	MSort(L.elem, t, 0, L.length - 1);
}

////////////////////////////////////////////////////////////////地址排序

void ReArrange(SqList &L, int adr[])
//adr给出顺序表L的有序次序,即L.elem[adr[i]]是第i小的记录
//本算法按adr重排L.elem使其有序
{
	ElemType temp;
	int j, k;
	for (int i = 0; i < L.length; i++)
	{
		if (adr[i] != i)
		{
			temp = L.elem[i];
			j = i;
			while (adr[j] != i)
			{
				k = adr[j];
				L.elem[j] = L.elem[k];
				adr[j] = j;
				j = k;
			}
			L.elem[j] = temp;
			adr[j] = j;
		}
	}
}

void AdrSort(SqList &L)
//根据记录L得到顺序表有序次序adr[]
{
	int adr[LISTLEN + 1];
	int temp;
	for (int i = 0; i < L.length; i++)
		adr[i] = i;
	for (int i = 0; i < L.length - 1; i++)
	{
		for (int j = i + 1; j < L.length; j++)
		{
			if (L.elem[adr[i]] > L.elem[adr[j]])
			{
				temp = adr[i];
				adr[i] = adr[j];
				adr[j] = temp;
			}
		}
	}
	ReArrange(L, adr);
}

main.cpp

#include"sort.h"
 
int main()
{
	SqList L;//顺序表
//	InitList(L);//已重载函数开辟顺序表空间默认为100
	InitList(L,10);//已重载函数后一个参数表示开辟的顺序表空间大小
//	int dlta[10]={5,3,1};//定义增量数组
	GetRandomNum(L);//已重载函数获得随机数默认范围0~99
//	GetRandomNum(L,10);//已重载函数获得随机数后一个参数表示数值范围上限
	PrintList(L);//打印
//	Qsort(L);
//	ShellSort(L,dlta,3);//对顺序表L进行希尔排序
//	HeapSort(L);
	MergeSort(L);
//	AdrSort(L);
	PrintList(L);//打印
	system("pause");
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注