文章目录
一、前言
数据结构只有五个考点:链表(包括栈和队列)、二叉树、图、查找、排序
排序三考点:所有排序算法比较 + 各个排序算法的原理 + 各个排序算法的特点
二、简单插入排序
2.1 demo + 运行结果
#include <iostream>
using namespace std;
void InsertSort(int r[],int n) //0号单元为暂存单元和监视哨
{
int j=0;
for(int i=2; i<=n; i++)
{
r[0]=r[i]; //用于暂存待排序元素
for ( j=i-1; r[0]<r[j]; j--) //寻找合适的插入位置
r[j+1]=r[j]; //移动
r[j+1]=r[0];
}
}
int main()
{
int a[5];
for (int i=0; i<5; i++)
cin>>a[i];
cout<<endl;
InsertSort(a,5);
for (int i=1; i<5; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
2.2 特点:简单插入排序
简单插入排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、只有相邻移动,没有跳动,是一种稳定的排序;
4、适用于序列基本有序的情况。
三、希尔排序
概要:希尔排序,一种高级排序方式,可以认为是简单插入排序的升级版
3.1 Demo + 运行结果
#include <iostream>
using namespace std;
void shellSort(int r[],int n)
{
for (int d=n/2; d>=1; d=d/2)
{
for (int i=d+1; i<=n; i++) //d为增量
{
r[0]=r[i]; //0号元素用于暂存 没有意义
int j=0;
for ( j=i-d; j>0&&r[0]<r[j]; j=j-d)
r[j+d]=r[j]; //记录每次移动d个位置,跳跃移动
r[j+d]=r[0];
}
}
}
int main()
{
int a[6];
for (int i=0; i<6; i++)
cin>>a[i];
cout<<endl;
shellSort(a,6);
for (int i=1; i<6; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
3.2 特点:希尔排序
希尔排序:
1、时间复杂度为O(nlgn)~O(n^2),这是大量重复实验的结果;
2、空间复杂度为O(1),一个暂存哨兵;
3、存在跳动移动,是一种不稳定的排序。
四、冒泡排序
概要:冒泡排序,一种低级排序,便于理解
4.1 Demo + 运行结果
#include <iostream>
using namespace std;
void bubbleSort(int r[],int n)
{
int exchange=n;
while(exchange!=0)
{
int bound=exchange;
exchange=0;
for (int j=1; j<bound; j++)
{
if(r[j]>r[j+1])
{
r[0]=r[j]; //0号元素用于交换暂存
r[j]=r[j+1];
r[j+1]=r[0];
exchange=j;
}
}
}
}
int main()
{
int a[6];
for (int i=0; i<6; i++)
cin>>a[i];
cout<<endl;
bubbleSort(a,6);
for (int i=1; i<6; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
4.2 特点:冒泡排序
冒泡排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、只有相邻移动,没有跳动,是一种稳定的排序。
五、快速排序(面试重点)
概要:快速排序,一种高级排序,可以看作是冒泡排序的升级版
5.1 Demo + 运行结果
#include <iostream>
using namespace std;
int Partition(int r[],int first,int _end)
{
int i=first;int j=_end;
while(i<j)
{
while(i<j && r[i]<=r[j]) j--;
if(i<j)
{
int temp=r[i];
r[i]=r[j];
r[j]=temp;
i++;
}
while(i<j && r[i]<=r[j]) i++;
if(i<j)
{
int temp=r[i];
r[i]=r[j];
r[j]=temp;
j--;
}
}
return i;
}
void QuickSort(int r[],int first,int _end)
{
if(first<_end)
{
int pivot=Partition(r,first,_end);
QuickSort(r,first,pivot-1);
QuickSort(r,pivot+1,_end);
}
}
int main()
{
int a[6];
for (int i=0; i<6; i++)
cin>>a[i];
cout<<endl;
QuickSort(a,0,5);
for (int i=0; i<6; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
5.2 特点:快速排序
快速排序:
1、时间复杂度为O(nlgn);
2、空间复杂度为O(1),一个交换变量(交换时合理利用加减可以省略此变量);
3、存在跳动,是一种不稳定的排序;
六、简单选择排序
概要:简单选择排序,一种低级排序方式,容易理解
6.1 Demo + 运行结果
#include <iostream>
using namespace std;
void selectSort(int r[],int n)
{
for (int i=1; i<n; i++)
{
int index=i;
int j=0;
for (j=i+1; j<=n; j++)
{
if(r[j]<r[index])
{
r[0]=r[j]; //0号元素用于暂存玩车个交换
// 其实可以不用这样,使用加减法可以不需要暂存元素,这里方便读者理解,用简单的方式
r[j]=r[index];
r[index]=r[0];
}
}
if(index!=i)
{
r[0]=r[i];
r[i]=r[index];
r[index]=r[0];
}
}
}
int main()
{
int a[6];
for (int i=0; i<6; i++)
cin>>a[i];
cout<<endl;
selectSort(a,6);
for (int i=1; i<6; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
6.2 特点:简单选择排序
简单选择排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存元素用于实现交换(不是必须,可以用两数加减法实现交换两数);
3、存在元素跳动,是一种不稳定的排序;
4、没有偏好适用情况,因为最好最坏平均时间复杂度均为O(n^2)
七、堆排序
概要:堆排序,一种高级排序方式,可以看作是简单选择排序的升级版
7.1 Demo + 运行结果
#include <iostream>
using namespace std;
void shift(int r[],int k,int m)
{
int i=k,j=2*i; // i 为某个结点 2*i为该结点的左孩子
while(j<=m) // 其左孩子没到结束 说明该结点还是非叶子结点,因为叶子结点是没有左孩子的
{
if(j<m && r[j]<r[j+1] ) j++; //j和j+1 比较左右孩子,j指向较大者
if(r[i]>r[j]) break; //当根结点大于左右孩子中较大者,跳出本次循环
else //否则,交换根节点和左右孩子较大者
{
r[0]=r[j]; //0号元素用于交换暂存
r[j]=r[i];
r[i]=r[0];
i=j;
j=2*i;
}
}
}
void heapSort(int r[],int n)
{
for (int i=n/2; i>=1; i--)
shift(r,i,n);
for (int i=1; i<n; i++)
{
r[0]=r[1]; //0号元素用于交换暂存
r[1]=r[n-i+1];
r[n-i+1]=r[0];
shift(r,1,n-i);
}
}
int main()
{
int a[6];
for (int i=0; i<6; i++)
cin>>a[i];
cout<<endl;
heapSort(a,6);
for (int i=1; i<6; i++)
{
cout<<a[i];
cout<<" ";
}
cout<<endl;
return 0;
}
运行结果:
7.2 特点:堆排序
堆排序:
1、时间复杂度为O(nlgn),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、存在跳动,是一种不稳定的排序;
4、适用于选出最小前几个元素和最大的前几个元素
八、面试金手指(排序算法的原理 + 排序算法的特点)
数据结构只有五个考点:链表(包括栈和队列)、二叉树、图、查找、排序
排序三考点:所有排序算法比较 + 各个排序算法的原理 + 各个排序算法的特点
各个排序算法特点先上这六个,排序算法原理以后再上。
简单插入排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、只有相邻移动,没有跳动,是一种稳定的排序;
4、适用于序列基本有序的情况。
希尔排序:
1、时间复杂度为O(nlgn)~O(n^2),这是大量重复实验的结果;
2、空间复杂度为O(1),一个暂存哨兵;
3、存在跳动移动,是一种不稳定的排序。
冒泡排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、只有相邻移动,没有跳动,是一种稳定的排序。
快速排序:
1、时间复杂度为O(nlgn);
2、空间复杂度为O(1),一个交换变量(交换时合理利用加减可以省略此变量);
3、存在跳动,是一种不稳定的排序;
简单选择排序:
1、时间复杂度为O(n^2),因为两个循环;
2、空间复杂度为O(1),一个暂存元素用于实现交换(不是必须,可以用两数加减法实现交换两数);
3、存在元素跳动,是一种不稳定的排序;
4、没有偏好适用情况,因为最好最坏平均时间复杂度均为O(n^2)
堆排序:
1、时间复杂度为O(nlgn),因为两个循环;
2、空间复杂度为O(1),一个暂存哨兵;
3、存在跳动,是一种不稳定的排序;
4、适用于选出最小前几个元素和最大的前几个元素
九、小结
六种排序算法(简单插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序),完成了。
天天打码,天天进步!!!