算法---排序(C++实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014573686/article/details/88320969

冒泡排序

快速排序

插入排序

选择排序

希尔排序

堆排序

归并排序

1.冒泡排序
冒泡排序采用两两比较的方式。如果要由小到大排序,并且从前往后遍历,那么将大的往后放,第一重循环是比较几轮,也就是数组个数,第二重循环是从 0 到总数减去轮数。

// 冒泡排序
void myBubble(vector<int> &values)
{
       int temp = 0;
       for (int i = 0; i < values.size(); i++)
       {
              for (int j = 0; j < values.size() - i - 1; j++)
              {
                     // 由小到大
                     if (values[j] > values[j+1])
                     {
                           temp = values[j + 1];
                           values[j + 1] = values[j];
                           values[j] = temp;
                          /* 不用额外的空间方法
                           values[j + 1] ^= values[j];
                           values[j] ^= values[j+1];
                           values[j+1] ^= values[j];
                          */
                     }
              }
       }
}

2.快速排序
快速排序就是选择一个基准数据,然后在数组中 后前 依次判断,如果是由小到大的,那么大的应该在基准右侧,小的在基准左侧,所以找到不满足的就交换位置。
注意:快速排序在递归时,必须判断左侧标志否小于右侧,否则递归无法退出
如果基准选择的是最左侧的数据,那么就应该先从右侧判断,因为左侧基准已经记录的值,所以右侧找到需要交换的数据可以赋值,否则会覆盖掉数组的值
在比较的时候必须用 <= 和 >= ,否则碰到两个相同的数据就会陷入死循环。

// 快速排序
int partition(vector<int> &values, int low, int high)
{
       if (low >= 0)
       {
              int temp = values[low];
              while (low < high)
              {
                     // 由小到大
                     while (low < high && values[high] >= temp)
                     {
                           high--;
                     }
                     values[low] = values[high];
                     while (low < high && values[low] <= temp)
                     {
                           low++;
                     }
                     values[high] = values[low];
              }
              values[low] = temp;
       }
       return low;
       
}
void quickSort(vector<int> &values,int low, int high)
{
       if (low < high)
       {
              int middle = partition(values, low, high);
              quickSort(values,low,middle - 1);
              quickSort(values, middle + 1, high);
       }
}

3.插入排序
遍历元素,与前边的元素比较,从小到大的话,如果需要前置,那么将上一个元素后移,直到找到合适位置,第二重循环的 j 可以看作指向 坑 在哪,将前边的元素放进坑中。

// 插入排序
void insertSort(vector<int> &values)
{
       for (size_t i = 1; i < values.size(); i++)
       {
              int temp = values[i];
              // 由小到大
              size_t j = i;
              for (; j >= 1 && temp < values[j - 1]; j--)
              {
                     values[j] = values[j - 1];
              }
              values[j] = temp;
       }
}

4.希尔排序
与直接插入排序相似,只不过比较不是逐个比较,而是有一个增量,每次移动一个增量。

// 希尔排序
void shellSort(vector<int> &values)
{
       if (values.size() > 0)
       {
              int gap = values.size();
              while (1 != gap)
              {
                     gap /= 2;
                     for (size_t i = gap; i < values.size(); i++)
                     {
                           int temp = values[i];
                           int j = i;
                           for (; j >= gap && temp < values[j - gap]; j -= gap)
                           {
                                  values[j] = values[j - gap];
                           }
                           values[j] = temp;
                     }
              }
       }
}

5.选择排序(擂台法)
依次遍历数组,由小到大是找到最小值并且记录下标,然后交换数值

// 选择排序
void selectSort(vector<int> &values)
{
       if (values.size() > 0)
       {
              for (size_t i = 0; i < values.size(); i++)
              {
                     int min = values[i];
                     size_t n = i;
                     size_t j = i + 1;
                     for (; j < values.size(); j++)
                     {
                           if (min > values[j])
                           {
                                  min = values[j];
                                  n = j;
                           }
                     }
                     values[n] = values[i];
                     values[i] = min;
              }
       }
}

6.堆排序
堆排序首先是建立一个大顶堆,即所有的父节点都大于子节点的二叉树,然后取出最大值:与最后一个交换,将前边的继续建立大顶堆,然后继续取最大的放到最后,直至结束。
建立大顶堆的算法:因为初始数组,只有前一部分有子节点,所以,从中间往前来建立,如果当前节点小于两个子节点中最大的子节点,那么就交换位置,然后继续判断在交换后的位置是否子节点仍然大于父节点,大于的话继续交换,直至不再大于,就到下一个父节点,从而建立成功。

// 堆排序
int leftChild(int i)
{
       return 2 * i + 1;
}
void swap(vector<int> &values, int i, int j)
{
       int temp = values[i];
       values[i] = values[j];
       values[j] = temp;
}
void createMaxHeap(vector<int> &values, int i, int length)
{
       int child = 0;
       int temp = values[i];
       for (; leftChild(i) < length; i = child)
       {
              child = leftChild(i);
              if (child != length - 1 && values[child] < values[child + 1])
              {
                     child++; // 选择大的子节点
              }
              if (temp < values[child])
              {
                     values[i] = values[child];  // 如果子节点大,就与父节点交换
              }
              else
              {
                     break;
              }
       }
       values[i] = temp;  //
}
void heapSort(vector<int> &values)
{
       for (int i = values.size() / 2; i >= 0; i--)
       {
              createMaxHeap(values,i,values.size());
       }
       for (size_t i = values.size() - 1; i > 0 ; i--)
       {
              swap(values,0,i);
              createMaxHeap(values,0,i);
       }
}

7.归并排序
首先是 归 即递归,递归来分治数组,不断的划分数组。
然后是 并 即合并,合并来排序。
所以可以先设计合并有序数组的算法,创建中间数组来存储合并后的数据。
然后递归调用即可。

// 归并排序
void mergeArray(vector<int> &values, int left, int mid, int right, vector<int> & temp_vec)
{
       int k = 0;
       int i = left;
       int j = mid + 1;
       // 合并有序数组
       while (i <= mid && j <= right)
       {
              if (values[i] <= values[j])
              {
                     temp_vec[k++] = values[i++];
              }
              else
              {
                     temp_vec[k++] = values[j++];
              }
       }
       // 左边的没有排完
       while(i <= mid)
       {
              temp_vec[k++] = values[i++];
       }
       // 右边的没有排完
       while (j <= right)
       {
              temp_vec[k++] = values[j++];
       }
       // 赋值
       for (size_t m = 0; m < k; m++)
       {
              values[m + left] = temp_vec[m];
       }
}
void mergeSort(vector<int> &values, int left, int right)
{
       if (left < right)
       {
              int mid = (left + right) / 2;
              mergeSort(values, left, mid);
              mergeSort(values,mid + 1,right);
              vector<int> temp_vec = values;
              mergeArray(values,left,mid,right,temp_vec);
       }
}

猜你喜欢

转载自blog.csdn.net/u014573686/article/details/88320969