冒泡排序:
依次比较相邻的两个元素,如果前者大于后者,则交换顺序。第一趟完成后最后的元素是最大的,然后针对所有的元素重复以上的步骤,除了最后一个。时间复杂度n^2
void bubblesort(vector<int>& arr)
{
for (int i = 0; i < arr.size()-1; i++)
{
for (int j = 0; j < arr.size()-1-i; j++)
{
if (arr[j]> arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
选择排序:
在序列中,找到最小元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
void selectionsort(vector<int>& arr)
{
for (int i = 0;i < arr.size()-2;i++)
{
int min = arr[i],index=i;
for (int j = i+1;j < arr.size()-1;j++)
{
if (min>arr[j])
{
min = arr[j];
index = j;
}
}
arr[j] = arr[i];
arr[i] = min;
}
}
插入排序:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移到下一位置
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到该位置中
6.重复步骤2
void insertionsort (vector<int>& arr)
{
for (int i = 1;i < arr.size()-1;i++)
{
int temp = arr[i];
for (int j = i-1;j >= 0&& temp < arr[j];j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
快速排序:
选定第一个数作为基准,将设置左右两个指针,目标是将比基准数大的数放在右边,小的数放在左边,如果有不满足的条件的,则两个指针交换,直到两个指针重合,将此时所指的数和基准数交换。
void quicksort(vector<int>& arr, int left, int right)
{
if(left>right)
return;
int i = left, j = right, temp = arr[left];
while (i < j) //如果i==j,此时则为正中心的位置,需要把基准数换过去
{
while(i < j && arr[j]>= temp) // 从右向左找第一个小于x的数
j--;
while(i < j && arr[i]<= temp) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
{
int t = arr[i];
arr[i] = arr[j];
arr[j] =t;
}
}
arr[left] = arr[i];
arr[i] =temp;
quicksort(arr, left, i - 1); // 递归调用
quicksort(arr, i + 1, right);
}
堆排序:
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
堆排序的基本思路:
a.将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
class Solution {
public:
*/
void heapAdjust(vector<int>& arr, int start, int end) {
int temp = arr[start];
for(int i=2*start+1; i<=end; i*=2) {
//左右孩子的节点分别为2*i+1,2*i+2
//选择出左右孩子较小的下标
if(i < end && arr[i] < arr[i+1]) {
i ++;
}
if(temp >= arr[i]) {
break; //已经为大顶堆,=保持稳定性。
}
arr[start] = arr[i]; //将子节点上移
start = i; //下一轮筛选
}
arr[start] = temp; //插入正确的位置
}
void heapSort(vector<int>& arr) {
if(arr == null || arr.length == 0)
return ;
//建立大顶堆
for(int i=arr.length/2; i>=0; i--) {
heapAdjust(arr, i, arr.length-1);
}
for(int i=arr.length-1; i>=0; i--) {
swap(arr, 0, i);
heapAdjust(arr, 0, i-1);
}
}
void swap(vector<int>& arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
排序算法的稳定性:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。