C++——排序算法代码实现

梦想的初衷 提交于 2020-01-25 09:26:18

1.头文件&&结构体定义

#include<iostream>
#include<ctime>
using namespace std;
#define MaxLength 500    //定义最大长度

typedef int ElemType;
typedef struct SqList
{
	int length;//长度
	ElemType *data;    //定义data指针用于后续申请空间
}SqList;

void InitSqList(SqList &L)//初始化----申请空间
{
	L.data = new ElemType[MaxLength + 1];
}

2.插入排序

void InsertSqListSort(SqList&L)//插入排序
{
	L.data[0] = 0;
	int i = 2, j;                     //定义i,j用于后续循环计数
	for (i; i <= L.length; i++)
	{
		if (L.data[i] < L.data[i - 1])//如果后一个数比前一个数小
		{
			L.data[0] = L.data[i];//待插入的数存入哨兵L.data[0]中
			L.data[i] = L.data[i - 1];//把大的值直接放在后一个位置
			for (j = i - 2; L.data[0] < L.data[j]; j--)//如果哨兵的值比前面的小
			{
				L.data[j + 1] = L.data[j]; //满足条件就把比它大的数向后移动
			}
			L.data[j + 1] = L.data[0];//找到哨兵的值应该对应的地方
		}
	}
}

3.选择排序

void SelectSqListSort(SqList&L)  //选择排序
{
	for (int i = 1; i < L.length; i++)
	{
		int k = i;       //k指向已排好序序列的下一数,最开始一个都没有排好序
		for (int j = i + 1; j <= L.length; j++)
		{
			if (L.data[j] < L.data[k])     //找到没排好序序列里面的最小数
			{
				k = j;//j对应的数据比k对应数据小,就把最小数的下标记录下来
			}
		}
		if (k > i)      //利用哨兵交换数据
		{
			L.data[0] = L.data[k];
			L.data[k] = L.data[i];
			L.data[i] = L.data[0];
		}
    }
} 

4.冒泡排序

void BubbleSqListSort(SqList&L)   //冒泡排序
{
	int is_changed_flag = 0;  //如果没有交换,flag=0,反之flag=1
	for (int i = 1; i < L.length; i++)
	{
		if (L.data[i] > L.data[i + 1])  //利用哨兵交换数据
		{
			L.data[0] = L.data[i];
			L.data[i] = L.data[i + 1];
			L.data[i + 1] = L.data[0];
			is_changed_flag = 1;     //修改flag为1
		}
		if (!is_changed_flag)  break;  //如果已经没有交换,终止循环
	}
}

5.双向冒泡排序

void DoubleBubbleSort(SqList&L)  //双向冒泡排序
{
	int low = 1;    //最初low指向第一个元素    
	int high = L.length;     //最初high指向最后一个元素
	while (low < high)     //当low<high时进入循环
	{
		bool is_changed_flag = true;//置flag为true
		for (int i = low; i < high; i++)    //从前向后两两比较
		{
			if (L.data[i] > L.data[i + 1])  //利用哨兵交换
			{
				L.data[0] = L.data[i];
				L.data[i] = L.data[i + 1];
				L.data[i + 1] = L.data[0];
			}
			is_changed_flag = false;    //修改flag为false
		}             //end for
		if (is_changed_flag)   break;  //flag没被修改过就结束
		high--;    //high指针前移

		is_changed_flag = true; //重新置flag为true
		for (int j = high; j >= low; j--)        //从后向前两两比较
		{
			if (L.data[j] > L.data[j + 1])   //利用哨兵交换
			{
				L.data[0] = L.data[j];
				L.data[j] = L.data[j + 1];
				L.data[j + 1] = L.data[0];
			}
			is_changed_flag = false;  //修改flag为flag
		}             //end for
		if (is_changed_flag)   break;   //flag没被修改过就结束
		low++;      //low指针后移
	}     //end while
	
}

6.折半插入排序

void BinaryInsertSqListSort(SqList&L)//折半插入排序
{
	int low, high, mid;            //定义三个指针mid,low,high
	for (int i = 2; i <= L.length; i++)
	{
		L.data[0] = L.data[i];     //把值给哨兵暂存
		low = 1; high = i - 1;
		while (low <= high)       //当low<=high,进入循环
		{
			mid = (low + high) / 2;       //mid
			if (L.data[i] < L.data[mid]) high = mid - 1;
			else low = mid + 1;       
		}
		for (int j = i - 1; j >= high + 1; j--)   //把插入位置之后到i-1的内容全部都后移
			L.data[j + 1] = L.data[j];
		L.data[high + 1] = L.data[0];    //利用哨兵,将插入的值插进去
	}
}

7.希尔插入排序

void ShellInsert(SqList&L,int index)   //希尔插入法
{
	int i, j;
	for (i = index + 1; i <= L.length; i++)
	{
		if (L.data[i] < L.data[i - index])
		{
			L.data[0] = L.data[i];  //哨兵暂存L.data[i]的值
			L.data[i] = L.data[i - index];//把大的值直接放在后一个位置
			for (j = i - index; j >= 0 && L.data[0] < L.data[j]; j = j - index)
			{
				L.data[j + index] = L.data[j];
			}
			L.data[j + index] = L.data[0];
		}
	}
		
}
void ShellInsertSqListSort(SqList&L,int dt[],int dtlength)   //调用插入进行排序
{
	
	for (int k = 0; k < dtlength; k++)
	{
		ShellInsert(L, dt[k]);
	}
}

8.快速排序

int QuickSortPart(SqList&L,int low,int high)  //快速排序
{
	L.data[0] = L.data[low];
	int piv = L.data[0];
	for (int i = 1; i < L.length; i++)
	{
		while (low < high)      
		{
			while (low < high&&piv <= L.data[high])  high--;//先把指挥棒交给high
			L.data[low] = L.data[high];
			while (low < high&&L.data[low] <= piv)  low++;//把指挥棒交给low
			L.data[high] = L.data[low];
		}         //end while
	}             //end for
	L.data[low] = L.data[0];
	return low;   //返回下标
}
void QuickSort(SqList&L,int low,int high)  //快速排序
{
	int piv;    
	if (low < high)
	{
		piv = QuickSortPart(L, low, high); //用piv记录返回值(low)
		QuickSort(L, low, piv - 1);   //调用递归
		QuickSort(L, piv+1, high);
	}
}

void QuickSqListSort(SqList&L)  //快速排序
{
	int low = 1, high = L.length;
	QuickSort(L, low, high);
}

9.归并排序

void Merge(int a[], int low, int high, int mid)//合并两组数字 
{
	int k = 0; 
	int left = low;
	int right = mid + 1;  //将数组a分为两个部分,left指向左一,right指向右一 
	int *temp=new int[high - low + 1];//用来存排序数的临时数组 
	while (left <= mid && right <= high)//当两组数字都未全部移入临时数组 
	{
		if (a[left] > a[right])       //把小数存入temp中,指针后移
			temp[k++] = a[right++];
		else
			temp[k++] = a[left++];
	}
	while (left <= mid)          //当第二组数中还有数未移入临时数组 
		temp[k++] = a[left++];
	while (right <= high)        //当第二组数中还有数未移入临时数组 
		temp[k++] = a[right++];
	k = 0;
	for (int t = low;t <= high; t++,k++)   //将临时数组的数移入原数组 
		a[t] = temp[k];
	delete[]temp;
}


void MergeSort(int a[], int low, int high)//归并排序 
{
	if (low < high - 1)//如果该组数字个数大于2 
	{
		int mid = (low + high) / 2;
		MergeSort(a, low, mid);
		MergeSort(a, mid + 1, high);//分割 
		Merge(a, low, high, mid);//合并 
	}
	else if (low == high - 1)//如果该组数字个数等于2 
	{
		if (a[low] > a[high]) //如果前一个数字比后一个数字大,交换 
		{
			int temp = a[low]; 
			a[low] = a[high];
			a[high] = temp;
		}
	}
	//如果该组数字只剩一个,不用处理 
}

void MergeSqListSort(SqList&L)  //调用归并排序
{
	MergeSort(L.data, 1, L.length);
}

10.堆排序

void HeapAdjust(SqList&L, int s, int m)  //堆调整
{
	int temp = L.data[s];   //用temp记录L.data[s]
	for (int j = 2 * s; j <= m; j *= 2)
	{
		if (j < m&&L.data[j] < L.data[j + 1]) ++j;  //j记录值大的结点下标
		if (temp >= L.data[j]) break;
		L.data[s] = L.data[j]; s = j;
	}
	L.data[s] = temp;     //用temp恢复L.data[s]的值
}

void CreateHeap(SqList&L)  //创建堆
{
	/*利用L.length/2求得最后一个分支结点,依次-1求得之前的分支结点*/
	for (int i = L.length / 2; i > 0; i--)
		HeapAdjust(L, i, L.length);  //调用堆调整进行创建
}

void HeapSort(SqList &L)  //堆排序
{
	CreateHeap(L);
	for (int i = L.length; i > 1; i--)
	{
		int temp = L.data[1];  //借用临时变量temp互换L.data[1]和L.data[i]
		L.data[1] = L.data[i];
		L.data[i] = temp;
		HeapAdjust(L, 1, i - 1);  //堆调整
	}
}

11.基数排序

#define MaxSize 200	    //待排序元素的最大个数
#define N 8         	//待排序元素的实际个数
#define Key_MaxNum 6	//关键字项数的最大值
#define Radix 10		//关键字基数,10表示十进制数字可以分为十组
typedef struct
{
	int key[Key_MaxNum]; 	//存放关键字
	int next;
}SListCell;        //静态链表的结点,存放待排序元素

typedef struct
{
	SListCell data[MaxSize];		//存储元素,data[0]为头结点
	int keynum;				//每个元素的当前关键字个数
	int length;					//静态链表的当前长度
}*SLList;              //静态链表,存放元素序列
 int trans(char c)     //将字符c转化为对应的整数
{
	return c - '0';
}
void Distribute(SListCell data[], int i, addr f, addr r)
{
	int j, p;
	for (j = 0; j < Radix; j++)			//初始化各个子表
		f[j] = 0;
	for (p = data[0].next; p; p = data[p].next)
	{
		j = trans(data[p].key[i]);		//将关键字转换为数字
		if (!f[j])				//f[j]是空表,则f[j]指示第一个元素
			f[j] = p;
		else
			data[r[j]].next = p;
		r[j] = p;		//将p所指的结点插入第j个子表中
	}
}
void Collect(SListCell data[], addr f, addr r)
//收集,按key[i]将f[0..Radix-1]所指各子表依次链接成一个静态链表
{
		int j, t;
	for (j = 0; !f[j]; j++);	//找第一个非空子表
	data[0].next = f[j];
	t = r[j];			//r[0].next指向第一个非空子表中第一个结点
	while (j < Radix - 1)
	{
		for (j = j + 1; j < Radix - 1 && !f[j]; j++);		//找下一个非空子表
		if (f[j])		//将非空链表连接在一起
		{
		data[t].next = f[j];
			t = r[j];
		}
	}
	data[t].next = 0;		//t指向最后一个非空子表中的最后一个结点
}
void RadixSort(SLList L) 
//基数排序,使得L成为按关键字非递减的静态链表,L.r[0]为头结点
{
	int i;
	addr f, r;
	for (i = 0; i < L.keynum; i++)	//由低位到高位依次对各关键字进行分配和收集
	{
		Distribute(L.data, i, f, r);		//第i趟分配
		Collect(L.data, f, r);			//第i趟收集
	}
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!