小工具知识网

当前位置: 首页 > 行业知识 > 非常完整的排序算法加练习题

行业知识

非常完整的排序算法加练习题

2026-11-05 06:55:43 来源:互联网转载

排序算法

何衍泓

所有的排序测试的头文件 0.sort_test.h

#pragma once#include#include#define SMALL_DATA_N 5000#define BIG_DATA_N 1000000void __init_Rand__(){printf("init rand\n");}bool check(int* arr, int l, int r){for (int i = l + 1; i  

选择排序(selection_sort)

  • 将数组分成“已排序区”和“待排序区”
  • 每一轮在“待排序区”选择一个最小值放入“已排序区”
  • 直到“待排序区”没有元素为止
    #define _CRT_SECURE_NO_WARNINGS 1#include#include#include#include"0.sort_test.h"#include#include#include//每次在待排序区中选择一个最小值放到已排序区的最后void selection_sort(int* arr, int l, int r){for (int i = l; i  

    正常版本的插入排序(insert_sort)

    • 将待排序区的第一个值与前面已排序区一个一个往前插队
    • 直到遇到比自己还小的就停止插队
      #define _CRT_SECURE_NO_WARNINGS 1#include#include#include#include"0.sort_test.h"#include#include#include//每次在将当前值向前插队void insert_sort(int* arr, int l, int r){for (int i = l + 1; i  l && arr[j]  

      无监督插入排序(unguarded_insert_sort)

      • 无监督版本主要是通过先把最小值放到前面来减少 j > l 的判断
        void unguarded_insert_sort(int* arr, int l, int r){int ind = l;for (int i = l + 1; i  arr[i]) ind = i;}while (ind > l)//为了插入算法的稳定性,一个一个向前交换{swap(arr[ind], arr[ind - 1]);ind--;}for (int i = l + 1; i  

        希尔排序(shell_sort)

        • 分组插入排序
        • 首先设置一个合适的步长序列,有希尔序列和hibbard序列
        • 希尔排序没有固定的时间复杂度,他的时间复杂度和步长序列有关
        • 按照步长对每个分组进行无监督插入排序
        • 直到执行到步长为 1 为止
          #define _CRT_SECURE_NO_WARNINGS 1#include#include#include#include"0.sort_test.h"#include#include#include//分组插入排序(希尔排序)void unguarded_insert_sort(int* arr, int l, int r, int step){int ind = l;for (int i = l + step; i  arr[i]) ind = i;}while (ind > l){swap(arr[ind], arr[ind - step]);ind -= step;}for (int i = l + 2 * step; i  

          冒泡排序(bubble_sort)

          • 外层循环 i 代表当前轮需要将待排序区的最大值放到 i 位置
          • 内层遍历待排序区,一个一个交换,将待排序区的最大值交换到 i 位置(稳定排序)
          • 优化:若遍历的时候没有发生任何一次交换则说明有序了,这个时候直接 break 即可
            #define _CRT_SECURE_NO_WARNINGS 1#include#include#include#include"0.sort_test.h"#include#include#includeusing namespace std;void bubble_sort(int* arr, int l, int r){for (int i = r - 1, cnt; i >= l + 1; i--)//执行 (n - 1) 轮{cnt = 0;for (int j = l; j  arr[j + 1]){swap(arr[j], arr[j + 1]);cnt = 1;}}if (cnt == 0) break;}return;}int main(){int* arr = getRandData(SMALL_DATA_N);TEST(bubble_sort, arr, SMALL_DATA_N);free(arr);return 0;}

            快速排序(quick_sort)

            • 首先在待排序区域找到一个基准值
            • 按照基准值大小分成两个区域
            • 递归对两个区域排序
              #define _CRT_SECURE_NO_WARNINGS 1#include#include#include#include"0.sort_test.h"//选择第一个作为基准值,并且一个一个交换来分区void quick_sort(int* arr, int l, int r){if (r - l val);            r = max(r,p->val);            p = p->next;        }        if(l == r) return head;        //注意不要向0取整,要向下取整(避免负数出现导致***循环)        int mid = (l + r)>> 1;        //使用链表头插法        ListNode *h1 = nullptr ,*h2 = nullptr,*q;        p = head;        while(p)        {            q = p->next;            if(p->valnext = h1;                h1 = p;            }else{                p->next = h2;                h2 = p;            }            p = q;        }        h1 = sortList(h1);        h2 = sortList(h2);        p = h1;        while(p->next) p = p->next;        p->next = h2;        return h1;    }};
              方法三:归并排序
              • 分治将链表对半切开
              • 可以利用虚拟头结点将两个链表串起来
              • 最后返回虚拟头结点的下一位即可
                /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode() : val(0), next(nullptr) {} *     ListNode(int x) : val(x), next(nullptr) {} *     ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */class Solution {public:    ListNode* merge_sort(ListNode* head,int n)    {        if(n next;        p->next = nullptr;        p = merge_sort(head,l);        q = merge_sort(q,r);        ListNode ret;        ListNode *new_head = &ret;        while(p || q)        {            if(q == nullptr || (p && p->valval)){                new_head->next = p;                new_head = p;                p = p->next;            }else{                new_head->next = q;                new_head = q;                q = q->next;            }        }        return ret.next;    }    ListNode* sortList(ListNode* head) {        if(head == nullptr || head->next == nullptr) return head;        int n = 0;        ListNode* p = head;        while(p)         {            n++;            p = p->next;        }        return merge_sort(head,n);    }};

                合并两个有序数组

                https://leetcode.cn/problems/merge-sorted-array/description/

                方法一:开辟一个额外数组
                • 开辟一个temp数组
                • 将 nums1 的数据放到 temp 里面
                • 归并排序到 nums1 中即可
                  class Solution {public:    void merge(vector& nums1, int m, vector& nums2, int n) {        if(n == 0) return ;        vector temp;        for(int i=0;ivalval)){                p->next = list1;                p = list1;                list1 = list1->next;            }else{                p->next = list2;                p = list2;                list2 = list2->next;            }        }        return ret.next;    }};

                  两个正序数组的中位数

                  https://leetcode.cn/problems/median-of-two-sorted-arrays/description/

                  • 先合并成一个正序数组
                  • 然后再在里面找到中位数即可
                    class Solution {public:    double findMedianSortedArrays(vector& nums1, vector& nums2) {        int n1 = nums1.size(),n2 = nums2.size();        double ans = 0.0;        vector temp;        int p1 = 0,p2 = 0;        while(p1

上一篇:黑龙江服务器云空间怎么用?

下一篇:web服务器怎么绑定域名访问?