【C++】顺序表的排序

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define MAXSIZE 20     //顺序表最大长度

typedef struct{
	int key;           //关键字项,关键字类型为整形
	char *otherinfo;   //其它数据项
}RedType;     //记录类型

typedef struct{
	RedType r[MAXSIZE+1];     //0号单元闲置
	int length;               //顺序表长度
}SqList;     //顺序表类型


//对顺序表L中的记录进行直接插入排序
void InsertSort(SqList &L)
{
	int i,j;
	for(i=2;i<=L.length ;i++)
	{
		if(L.r[i].key <L.r[i-1].key )
		{
			L.r[0]=L.r[i];
			for(j=i-1;L.r[j].key >L.r[0].key ;j--)
			{
				L.r[j+1]=L.r[j];
			}
			L.r[j+1]=L.r [0];
		}
	}
}

//对顺序表L中的记录进行折半插入排序
void BInsertSort(SqList &L)
{
	int i,j,low,mid,high;
	for(i=2;i<=L.length ;i++)
	{
		if(L.r[i].key <L.r[i-1].key )
		{
			L.r[0]=L.r[i];
			low=1;
			high=i-1;
			while(low<=high)
			{
				mid=(low+high)/2;
				if(L.r[0].key <L.r[mid].key ) high=mid-1;
				else low=mid+1;
			}
			for(j=i-1 ;j>=high+1;j--)
			{
				L.r [j+1]=L.r[j];
			}
			L.r[high+1]=L.r[0];
		}
	}
}

//对顺序表L中的记录进行一趟增量为dk的希尔排序
void ShellInsert(SqList &L,int dk)
{
	int i,j;
	for(i=1+dk;i<=L.length ;i++)
	{
		if(L.r[i].key <L.r[i-dk].key )
		{
			L.r[0]=L.r[i];
			for(j=i-dk;j>0 && L.r[j].key >L.r [0].key ;j=j-dk)
			{
				L.r[j+dk]=L.r[j];
			}
			L.r[j+dk]=L.r[0];
		}
	}
}

//对顺序表L中的记录按增量序列(存储在数组dt中)进行t趟希尔排序
void ShellSort(SqList &L,int dt[],int t)
{
	int i;
	for(i=0;i<t;i++)
	{
		ShellInsert(L,dt[i]);
	}
}

//对顺序表L中的记录进行冒泡排序
void BubbleSort(SqList &L)
{
	int i,j,flag=1;
	RedType t;
	for(i=L.length -1;i>=1&&flag;i--)
	{
		flag=0;
		for(j=1;j<=i;j++)
		{
			if(L.r [j].key >L.r[j+1].key )
			{
				flag=1;
				t=L.r [j];
				L.r[j]=L.r[j+1];
				L.r[j+1]=t;
			}
		}
	}
}

//对顺序表L中的子表L.r[low...high]进行一次划分,并返回枢轴位置
int Partition(SqList &L,int low,int high)
{
	L.r[0]=L.r[low];
	int pivotkey=L.r[low].key;
	while(low<high)
	{
		while(low<high&&L.r[high].key>=pivotkey) --high;
		L.r[low]=L.r[high];
		while(low<high&&L.r[low].key<=pivotkey) ++low;
		L.r[high]=L.r[low];
	}
	L.r[low]=L.r[0];
	return low;  //代码补充完整后,删除该行
}


//对顺序表L中的子序列L.r[low...high]进行快速排序
void QSort(SqList &L,int low,int high)
{
	if(low<high)
	{
		int pivotloc=Partition(L,low,high);
		QSort(L,low,pivotloc-1);
		QSort(L,pivotloc+1,high);
	}
}

//对顺序表L中的记录进行快速排序
void QuickSort(SqList &L)
{
	QSort(L,1,L.length);
}

//对顺序表L中的记录进行简单选择排序
void SelectSort(SqList &L)
{
	for(int i=1;i<L.length;++i)
	{
		int k=i;
		for(int j=i+1;j<=L.length;++j)
			if(L.r[j].key<L.r[k].key) k=j;
		if(k!=i)
			{RedType t=L.r[i];L.r[i]=L.r[k];L.r[k]=t;}
	}
}

//堆的调整,假设L.r[s+1...m]已经是一个大根堆,该操作将L.r[s...m]调整为以L.r[s]为根的大根堆
void HeapAdjust(SqList &L,int s,int m)
{
	RedType rc=L.r[s];
	for(int j=2*s;j<=m;j*=2)
	{
		if(j<m&&L.r[j].key<L.r[j+1].key) ++j;
		if(rc.key>=L.r[j].key) break;
		L.r[s]=L.r[j];s=j;
	}
	L.r[s]=rc;
}

//把顺序表L中的无序记录序列建成大根堆
void CreatHeap(SqList &L)
{
	int n=L.length;
	for(int i=n/2;i>0;--i)
		HeapAdjust(L,i,n);
}

//对顺序表L中的记录进行堆排序
void HeapSort(SqList &L)
{
	CreatHeap(L);
	for(int i=L.length;i>1;--i)
	{
		RedType x=L.r[1];
		L.r[1]=L.r[i];
		L.r[i]=x;
		HeapAdjust(L,1,i-1);
	}
}

//将有序表R[low...mid]和R[mid+1...high]归并为有序表T[low...high]
void Merge(RedType R[],RedType T[],int low,int mid,int high)
{
	int i=low,j=mid+1,k=low;
	while(i<=mid&&j<high)
	{
		if(R[i].key<=R[j].key) T[k++]=R[i++];
		else T[k++]=R[j++];
	}
	while(i<mid) T[k++]=R[i++];
	while(j<high) T[k++]=R[j++];
}

//将R[low...high]中的记录归并排序后放入T[low...high]中
void MSort(RedType R[],RedType T[],int low,int high)
{
	if(low==high) T[low]=R[low];
	else
	{
		mid=(low+high)/2;
		MSort(R,S,low,mid);
		MSort(R,S,mid+1,high);
		Merge(S,T,low,mid,high);
}

//对顺序表L中的记录进行归并排序
void MergeSort(SqList &L)
{
	MSort(L.r,L.r,1,L.length);
}
//创建顺序表:向顺序表L中添加10个记录,记录的关键字为1-100范围内的随机整数
void CreateList(SqList &L)
{
	int i;
	srand(time(0));
	for(i=1;i<=10;i++)
	{
		L.r[i].key =rand()%100+1;
	}
	L.length =10;
}

//输出顺序表L中各记录关键字的值,中间用空格分隔
void PrintList(SqList L)
{
	int i;
	for(i=1;i<=L.length ;i++)
	{
		cout<<L.r[i].key <<"  ";
	}
	cout<<endl;
}

//程序菜单
void showmenu()
{
	cout<<endl;
	cout<<"*************排序方法************************"<<endl;
	cout<<"1. 直接插入排序\t2. 折半插入排序"<<endl;
	cout<<"3. 希尔排序\t4. 冒泡排序"<<endl;
	cout<<"5. 快速排序\t6. 简单选择排序"<<endl;
	cout<<"7. 堆排序\t8. 二路归并排序"<<endl;
	cout<<"0.退出"<<endl;
	cout<<"请选择要执行的排序方法序号"<<endl;

}

int main()
{
	SqList L;   
	int n,dt[3]={5,3,1};    //dt中存放的是希尔排序时使用的三个增量
	CreateList(L);         //创建长度为10的顺序表L,表中记录的关键字为1-100范围内的随机整数
	showmenu();
	cin>>n;         //输出选择的排序方法序号
	while(n!=0)     //循环显示菜单,按0结束程序
	{
		if(n>=1&&n<=8)
		{
			cout<<"待排序记录初始关键字为:"<<endl;        
			PrintList(L);        //输出排序前表中各记录关键字的值
		}
		switch(n)     //根据选择的序号调用不同的排序方法
		{
		case 1:   
			cout<<"直接插入排序的结果为:"<<endl;
			InsertSort(L);    //直接插入排序
			PrintList(L);     //输出排序后各记录关键字的值
			break;
		case 2:
			cout<<"折半插入排序的结果为:"<<endl;
			BInsertSort(L);   //折半插入排序
			PrintList(L);
			break;
		case 3:
			cout<<"希尔排序的结果为:"<<endl;
			ShellSort(L,dt,3);    //希尔排序,(3趟)
			PrintList(L);
			break;
		case 4:
			cout<<"冒泡排序的结果为:"<<endl;
			BubbleSort(L);     //冒泡排序
			PrintList(L);
			break;
		case 5:
			cout<<"快速排序的结果为:"<<endl;
			QuickSort(L);    //快速排序
			PrintList(L);
			break;
		case 6:
			cout<<"简单选择排序的结果为:"<<endl;
			SelectSort(L);     //简单选择排序
			PrintList(L);
			break;
		case 7:
			cout<<"堆排序的结果为:"<<endl;
			HeapSort(L);    //堆排序
			PrintList(L);
			break;
		case 8:
			cout<<"快速排序的结果为:"<<endl;
			MergeSort(L);    //二路归并排序
			PrintList(L);
			break;
		default:
			cout<<"序号选择错误,请重新选择!"<<endl;
			break;

		}
		CreateList(L);    //每次排序后,重置L中的10个记录
		showmenu();
		cin>>n;
		system("cls");   //清屏
	}	
}
  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用c++实现的顺序:多文件编程,层次清晰,函数有注释 SeqList();//构造函数,存储的元素个数设为0 bool setLength(size_t length);//设置已经存储的元素个数 bool addElement(ElemType element);//把某个元素添加到顺序末尾 bool addElement(ElemType element , size_t n);//插入一个元素,使其成为第n个元素,其余元素后移 bool delElement();//删除所有的元素 bool delElement(size_t n);//删除第n个元素 bool delElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,把这个元素删除 bool replaceElement(ElemType element , size_t n);//使用一个元素,替换掉第n个元素 bool swapElement(size_t n1 , size_t n2);//把第n1个元素和第n2个元素交换 ElemType* getElement();//得到数组头的指针 ElemType* getElement(size_t n);//得到第n个元素的指针 size_t getLength();//得到存储的元素个数 size_t getMaxSize();//得到顺序容量 bool showElementDetail();//输出所有的元素细节 bool showElementDetail(size_t n);//输出第n个元素的细节 bool showElementDetail(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,输出元素所有细节 size_t findElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素位置 static int inputAInt(int min = 0,int max = 9,int defaultValue = -1);//从键盘读取,限制为一个min到max间的整数,非法情况返回defaultValue void startControlLoop();//打开控制界面 ~SeqList();//析构函数
对于顺序的逆置,可以使用双指针的方法来实现。首先,定义两个指针i和j,分别指向顺序的首尾元素。然后,交换i和j指向的元素,并将i向后移动一位,将j向前移动一位。重复这个过程,直到i和j相遇为止。这样就完成了顺序的逆置。 下面是一个示例代码实现: ```C++ #include <iostream> using namespace std; void reverse(int* arr, int size) { int i = 0; int j = size - 1; while (i < j) { swap(arr[i], arr[j]); i++; j--; } } int main() { int arr[] = {1, 2, 3, 4, 5}; int size = sizeof(arr) / sizeof(arr[0]); cout << "原始顺序:"; for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; reverse(arr, size); cout << "逆置后的顺序:"; for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; return 0; } ``` 对于顺序排序,可以使用常见的排序算法,例如冒泡排序、插入排序、选择排序等。这里以冒泡排序为例进行说明。冒泡排序的基本思想是从头到尾依次比较相邻的两个元素,如果前者大于后者,则交换这两个元素的位置。重复这个过程,直到整个顺序有序为止。 下面是一个示例代码实现: ```C++ #include <iostream> using namespace std; void bubbleSort(int* arr, int size) { for (int i = 0; i < size - 1; i++) { for (int j = 0; j < size - i - 1; j++) { if (arr[j] > arr[j + 1]) { swap(arr[j], arr[j + 1]); } } } } int main() { int arr[] = {5, 2, 4, 6, 1, 3}; int size = sizeof(arr) / sizeof(arr[0]); cout << "原始顺序:"; for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; bubbleSort(arr, size); cout << "排序后的顺序:"; for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cout0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值