插入排序
- 直接插入排序
直接插入排序 (Straight Insertion Sort) 是一种最简单的排序方法,其基本操作是将一条记录插入到已排好序的有序表中,从而得到一个新的、 记录数量增1的有序表。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void InsertSort(vector<int> &L)//直接插入排序
{
int i,j;
for(i=1;i<L.size();i++)
{
for(j=0;j<i;j++)//寻找待插入数字在已排好序列中的位置
{
if(L[i]<L[j])
break;
}
int t=L[i];
L.erase(L.begin()+i);//注意要删除原序列中的记录,不然数组的长度会一直增大,导致陷入死循环
L.insert(L.begin()+j,t);
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
InsertSort(L);
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
- 折半插入排序
直接插入排序采用顺序查找法查找当前记录在已排好序的序列中的插入位置,这个 “查找" 操作可利用 “折半查找” 来实现,由此进行的插入排序称之为折半插入排序。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void BInsertSort(vector<int> &L)//折半插入排序
{
int i,j;
for(i=1;i<L.size();i++)
{
int l=0,r=i-1;
while(l<=r)//折半查找待插入数字在已排好序列中的位置
{
int mid=(l+r)/2;
if(L[i]<L[mid])r=mid-1;
else l=mid+1;
}
int t=L[i];
L.erase(L.begin()+i);//注意要删除原序列中的记录,不然数组的长度会一直增大,导致陷入死循环
L.insert(L.begin()+l,t);
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
BInsertSort(L);
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
- 希尔排序
下面通过一个例子来理解希尔排序
初始关键字为:49 38 65 97 76 13 27 49 55 04
(1) 第一趟取增量 d1 =5 , 所有间隔为 5 的记录分在同一组,全部记录分成 5 组, 在各个组中分别进行直接插入排序。一趟排序结果: 13 27 49 55 04 49 38 65 97 76
(2) 第二趟取增量 d2 = 3, 所有间隔为 3 的记录分在同一组, 全部记录分成 3 组,在各个组中分别进行直接插入排序。二趟排序结果: I 3 04 49 38 27 49 55 65 97 76
(3)第三趟取增量 d3 = 1, 对整个序列进行一趟直接插入排序, 排序完成。三趟排序结果: 04 13 27 38 丕 49 55 65 76 97
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//2 20 9 67 4 32 78 12 88 12 33
void ShellInsert(vector<int> &L,int k)//希尔插入排序
{
int i,j;
for(i=k;i<L.size();i++)
{
for(j=i;j>=k;j-=k)//对在数组中距离为k的元素进行插入排序
{
if(L[j-k]>L[j])
{
int t=L[j-k];
L[j-k]=L[j];
L[j]=t;
}
}
}
}
void ShellSort(vector<int> &L,int t)
{
while(t>=2)
{
t/=2;
ShellInsert(L,t);//以t为增量进行希尔插入排序
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
ShellSort(L,L.size());
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
冒泡排序
冒泡排序(Bubble Sort)是一种最简单的交换排序方法,它通过两两比较相邻记录的关键字,如果发生逆序,则进行交换,从而使关键字小的记录如气泡一般逐渐往上 "漂浮"(左移),或者使关键字大的记录如石块一样逐渐向下 "坠落”(右移)。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void BubbleSort(vector<int> &L)//冒泡排序
{
int flag=1,m=1,i;
while(flag&&(m<L.size()-1))
{//每次把未排序序列中最大的元素放到最后
flag=0;
for(i=0;i<L.size()-m;i++)
{
if(L[i]>L[i+1])
{
int t=L[i];
L[i]=L[i+1];
L[i+1]=t;
flag=1;
}
}
m++;
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
BubbleSort(L);
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
快速排序
在待排序的 n个记录中任取一个记录(通常取第一个记录)作为枢轴(或支点),设其关键字为pivotkey。经过一趟排序后,把所有关键字小千pivotkey 的记录交换到前面,把所有关键字大于pivotkey的记录交换到后面,结果将待排序记录分成两个子表,最后将枢轴放置在分界处的位置。然后,分别对左、右子表重复上述过程,直至每一子表只有一个记录时,排序完成。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int Partition(vector<int> &L,int left,int right)//寻找分割点的位置
{
int key=L[left];
int l=left,r=right+1;
while(1)
{
while(L[++l]<key&&l<right);
while(L[--r]>key);
if(l>=r)break;
int t=L[l];
L[l]=L[r];
L[r]=t;
}
L[left]=L[r];
L[r]=key;
return r;
}
void QuickSort(vector<int> &L,int l,int r)//快速排序
{
int p;
if(l<r)
{
p=Partition(L,l,r);
QuickSort(L,l,p-1);
QuickSort(L,p+1,r);
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
QuickSort(L,0,L.size()-1);
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
选择排序
每次从剩余未排序数组中找出最小的关键字放在对应位置。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void SelectSort(vector<int> &L)//选择排序
{ int i,j;
for(i=0;i<L.size();i++)
{
int t=i,min=L[i];
for(j=i+1;j<L.size();j++)
{
if(min>L[j]){min=L[j];t=j;}
}
L[t]=L[i];
L[i]=min;
}
}
int main()
{
vector<int>L;
L.clear();
int x,n;
while(cin>>x)
{
L.push_back(x);
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
SelectSort(L);
int i=0;
while(i<L.size())
cout<<L[i++]<<" ";
return 0;
}
归并排序
2路归并排序将 R[low… high]中的记录归并排序后放入 T[low… high]中。 当序列长度等千 1 时,
递归结束, 否则:
1.将当前序列一分为二, 求出分裂点 mid = L(low+high)/2」;
2.对子序列 R[low… mid]递归,进行归并排序 仁 结果放入 S[low… mid]中;
3.对子序列 R[mid + 1…high]递归,进行归并排序, 结果放入 S[mid + 1…high]中;
4调用算法 Merge, 将有序的两个子序列 S[low… mid]和 S[mid + 1血gh]归并为一个有序的序列 T[low… high]。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int S[100];
void Merge(int *a,int *b,int l,int m,int r)//把m左右两端的序列合并到数组b
{
int i=l,j=m+1;
int k=l;
while(i<=m&&j<=r)
{
if(a[i]>a[j])
{
b[k++]=a[j++];
}
else
{
b[k++]=a[i++];
}
}
if(i>m)
while(j<=r)
{
b[k++]=a[j++];
}
else if(j>r)
while(i<=m)
b[k++]=a[i++];
}
void Copy(int *a,int *b,int l,int r)//把数组b复制到原来的数组中
{
int i;
for(i=l;i<=r;i++)
a[i]=b[i];
}
void MergeSort(int *L,int left,int right)//递归进行归并排序
{
if(left<right)
{
int mid=(left+right)/2;
MergeSort(L,left,mid);
MergeSort(L,mid+1,right);
Merge(L,S,left,mid,right);
Copy(L,S,left,right);
}
}
int main()
{
int L[100];
int x,n,i=0;
while(cin>>x)
{
L[i++]=x;
if(cin.get()=='\n')break;//录入数组遇到回车截至必须写这一行,不能按照c语言那种方式写
}
MergeSort(L,0,i-1);
n=i-1;
i=0;
while(i<=n)
cout<<L[i++]<<" ";
return 0;
}