八大排序

1.冒泡排序

  1. 算法步骤
    比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    针对所有的元素重复以上的步骤,除了最后一个
    持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    2.代码
void Bubble_Sort(int *num, int n)
{
 for (int i = 0; i < n; i++)
 {
  for (int j = 0; j < n; j++)
  {
   if (num[j] < num[j+1])//后面的大于前面的交换
   {
    int temp = num[j];
    num[j] = num[j+1];
    num[j+1] = temp;
   }
  }
 }
 
}

2.选择排序

  1. 算法步骤
    首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
    再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
    重复第二步,直到所有元素均排序完毕。
    2.代码
    void Selsction_Sort(int *num, int n)
    {
    for (int i = 0; i < n; i++)
    {
    int k = i;//记录选择位置
    for (int j = i; j < n; j++)
    {
    //后面位置上的元素大于选择位置上的元素更改记录位置
    if (num[k] < num[j])
    {
    k = j;
    }
    }
    if (k != i)//交换记录位置和选择位置
    {
    int temp = num[k];
    num[k] = num[i];
    num[i] = temp;
    }
    }
    }

3.插入排序

  1. 算法步骤
    将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
    从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

void Insertion_Sort(int *num, int n)
{
 //注意数组超限问题
 for (int i = 1; i < n; i++)
 {
  int k = num[i],j = i;
  for (; j > 0; j--)
  {
   if (k > num[j-1])//与当前位置的前一个位置比较
   {
    num[j] = num[j-1];
   }
   else
    break;
  }
  //此时j指向0位置
  num[j] = k;
 }
}

4.希尔排序

  1. 算法步骤
    选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
    按增量序列个数 k,对序列进行 k 趟排序;
    每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
    2.代码
void Shell_Sort(int *num, int n)
{
 int gap = 1;
 while (gap * 3 + 1 < n)//尽可能大的分组
  gap = gap * 3 + 1;
 while (gap > 0)
 {
  for (int i = 0; i < gap; i++)//循环次数
  {
   //使用插入排序方法
   for (int j = i + gap; j < n; j += gap)
   {
    int t = j, k = num[j];
    for (; t>=gap; t -= gap)//注意这层循环的结束位置
    {
     if (k > num[t - gap])
     {
      num[t] = num[t - gap];
     }
     else
      break;
    }
    num[t] = k;
   }
  }
  gap = (gap - 1) / 3;
 }
}

5,快速排序

  1. 算法步骤
    从数列中挑出一个元素,称为 “基准”(pivot);
    重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
    递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
  2. 代码
int Quick_Sort(int *num, int n, int left, int right)
{
 //退出条件
 if (left >= right || left > n - 1 || right > n - 1 || right <= 0 || left<0)
 {
  return -1;
 }
 int base = num[left];
 while (left != right)
 {
  while (num[right] < base && right > left) right--;
  num[left] = num[right];
  while (num[left] > base && right > left) left++;
  num[right] = num[left];
 }
 num[left] = base;
 return left;
}
void Quick_Sort_Re(int *num, int n, int left, int right)
{
 if (left >= right || left > n - 1 || right > n - 1 || right <= 0 || left<0)
 {
  return;
 }
 int baseid = Quick_Sort(num, n, left, right);
 if (baseid != -1)
 {
  Quick_Sort_Re(num, n, left, baseid - 1);
  Quick_Sort_Re(num, n, baseid + 1, right);
 }
}

6.归并排序

  1. 算法步骤
    申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
    设定两个指针,最初位置分别为两个已经排序序列的起始位置;
    比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
    重复步骤 3 直到某一指针达到序列尾;
    将另一序列剩下的所有元素直接复制到合并序列尾。

2.代码

void Merge_Sort(int *num, int *arr, int first, int last)//合并
{
 int mid = (last - first) / 2 + first;
 int i = first, j = mid + 1,k=0;
 while (i <= mid && j <= last)
  arr[k++] = num[i] > num[j] ? num[i++] : num[j++];
 while (i <= mid)
  arr[k++] = num[i++];
 while (j <= last)
  arr[k++] = num[j++];
 for (int m = 0; m < k; m++)
 {
  num[m + first] = arr[m];
 }
}
void Merge_Sort_Re(int *num, int *arr, int first, int last)//拆分
{
 if (first >= last)
  return;
 int mid = (last - first) / 2 + first;
 Merge_Sort_Re(num, arr, first, mid);
 Merge_Sort_Re(num, arr, mid+1, last);
 Merge_Sort(num, arr, first, last);
}

7.堆排序

  1. 算法步骤
    创建一个堆 H[0……n-1];
    把堆首(最大值)和堆尾互换;
    把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
    重复步骤 2,直到堆的尺寸为 1。
    2.代码
void Heap_Sort_Node(int *num, int n, int node)//调整节点
{
 if (2 * node + 1 > n - 1)
  return;
 int index = 0;
 if (2 * node + 2 > n - 1)
  index = 2 * node + 1;
 else
  index = num[2 * node + 1] < num[2 * node + 2] ? (2 * node + 1) : (2 * node + 2);
 if (num[index] < num[node])
 {
  int temp = num[node];
  num[node] = num[index];
  num[index] = temp;
  Heap_Sort_Node(num,n,index);
 }
}
void Heap_Sort(int *num, int n)
{
  return;
 //第一次堆调整节点将每个节点下的子节点都比父节点大
 for (int i = n / 2 - 1; i >= 0; i--)
  Heap_Sort_Node(num, n, i);
 //交换头尾
 swap(num[0], num[n - 1]);
 int qun = n - 1;
 while (qun)
 {
  Heap_Sort_Node(num, qun, 0);
  swap(num[0], num[qun-1]);
  qun--;
 }
}

8.基数排序

  1. 基数排序
    基数排序有两种方法:
    这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
    基数排序:根据键值的每位数字来分配桶;
    计数排序:每个桶只存储单一键值;
    桶排序:每个桶存储一定范围的数值;

2.代码

int GetMax(int* num)
{
 int temp = num[0];
 for (int i = 0; i < 10;i++)
 {
  if (temp < num[i])
  {
   temp = num[i];
  }
 }
 return temp;
}
void radix(int *num, int exp)
{
 int temp[10];
 int temp2[10] = { 0 };
 //1.统计位数上数据出现次数
 for (int i = 0; i < 10; i++)
 {
  temp2[(num[i] / exp) % 10]++;
 }
 //2.改变temp2使其数据成为排序后的位置..决定升序或降序
 for (int i = 1; i <10; i++)
 {
  temp2[i] += temp2[i - 1];
 }
 //3.放入临时的数组里面
 for (int i = 9; i >= 0; i--)
 {
  temp[temp2[(num[i] / exp)%10] - 1] = num[i];
  temp2[(num[i] / exp) %10]--;
 }
 //4.复制num中
 for (int i = 0; i < 10; i++)
 {
  num[i] = temp[i];
 }
}
int main()
{
 int num[10] = { 10, 15, 1, 2, 4, 25, 100, 50, 9, 6 };
 //1.得到最大值
 int Max = GetMax(num);
 //2.定义指数控制循次数以及每次的位数
 for (int exp = 1; Max / exp > 0; exp *= 10)
 {
  radix(num, exp);
 }
 //输出
 for (int n : num)
 {
  cout << n << endl;
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值