zoukankan      html  css  js  c++  java
  • 排序算法

    1. 冒泡排序

      两两比较相邻元素,逆序则交换,外层循环意思是总共要经过n-1轮冒泡,第i轮过后,第n-i个元素总是前n-i个数中的最大,所以按如下代码进行内外循环。

     1 int* bubbleSort(int* A, int n) {
     2         // write code here
     3         for(int i=n-1;i>=0;i--)
     4             for(int j=0;j<i;j++)
     5             {
     6                 if(A[j+1]<A[j])
     7                 {
     8                     int temp=A[j];
     9                     A[j]=A[j+1];
    10                     A[j+1]=temp;
    11                 }
    12             }
    13         return A;
    14     }

     1. 选择排序

      从i=0开始,内循环先找出第i+1到n-1中最小的数的下标,然后跟a[i]交换,保证每一次大循环后,a[i]都是[i,n-1]中的最小,因此最后一次循环为[i,n-1]只有两个元素的时候。代码如下:

     1 int* selectionSort(int* A, int n) {
     2         // write code here
     3         for(int i=0;i<n-1;i++)
     4         {
     5             int mini=i;
     6             for(int j=i+1;j<n;j++)
     7             {
     8                 mini=A[mini]>A[j]?j:mini;
     9             }
    10             if(mini!=i)
    11             {
    12                 int temp=A[mini];
    13                 A[mini]=A[i];
    14                 A[i]=temp;
    15             }
    16         }
    17         return A;
    18     }

     3. 插入排序

       插入排序思想是,记[0,i]是有序的,则在[0,i]中倒着查找插入第i+1个元素。

     1  int* insertionSort(int* A, int n) {
     2         // write code here
     3         for(int i=1;i<n;i++)
     4         {
     5             int temp=A[i];
     6             int j=i-1;
     7             while(j>=0&&temp<A[j])
     8             {
     9                 A[j+1]=A[j];
    10                 j--;
    11             }
    12             A[j+1]=temp;
    13         }
    14         return A;
    15     }

    4.归并排序

      归并排序关键点在于把两个有序数组融合起来的merge函数,通过不断划分子问题,用分治的思想,把一个大的数组分成两部分,每一部分再分成两部分,递归直到分到两个子数组都只有一个元素,自然这个子数组就是有序的,再把这样的两个子数组归并起来,自然得到规模为2的有序子数组,以此类推,最后归并成一个大的数组。

     1 class MergeSort {
     2 public:
     3     int* mergeSort(int* A, int n) {
     4         // write code here
     5         mergeSort(A,0,n-1);
     6         return A;
     7     }
     8     
     9     void mergeSort(int* A, int left, int right)
    10     {
    11         if(left==right)
    12             return;
    13         int mid=(left+right)/2;
    14         mergeSort(A,left,mid);
    15         mergeSort(A,mid+1,right);
    16         merge(A,left,mid,right);
    17         return;
    18     }
    19     
    20     void merge(int* A,int left,int mid,int right)
    21     {
    22         int* temp=new int[right-left+1];
    23         int l=left;
    24         int r=mid+1;
    25         int k=0;
    26         while(l<=mid&&r<=right)
    27         {
    28             if(A[l]<=A[r])
    29             {
    30                 temp[k++]=A[l++];
    31             }
    32             else
    33                 temp[k++]=A[r++];
    34         }
    35         while(l<=mid)
    36             temp[k++]=A[l++];
    37         while(r<=right)
    38             temp[k++]=A[r++];
    39         for(int i=0;i<k;i++)
    40             A[left+i]=temp[i];
    41     }
    42 };

     5. 快排

      其基本思想是:

      1. 分治法: 在 quickSort(A, 0,n-1) 中调用 quickSort(A, left,mid-1) 和 quickSort(A, mid+1,right) ,其中mid为枢纽所在的位置。

      2. 在数组中随机选择一个枢纽作为基准,将其放到数组的最右边后,遍历数组,将比其小的数放在其左边,大于其的数放在其右边。

      3. mid = partition(A,left,right) 该函数的思想是,用 int pivot = left-1; 指向小于枢纽的数的最后一个元素的位置,然后遍历该数组,最后返回 pivot 表示枢纽所在的位置。

    class QuickSort {
    public:
        int* quickSort(int* A, int n) {
            // write code here
            if(A==nullptr&&n<2)
                return A;
            srand((unsigned(time(NULL))));
            return quickSort(A, 0,n-1);
        }
        
        int* quickSort(int* A, int left, int right){
            if(left<right)
            {
                int random = left+rand()%(right-left+1);
                int temp=A[random];
                A[random]=A[right];
                A[right]=temp;
                int mid = partition(A,left,right);
                quickSort(A, left,mid-1);
                quickSort(A, mid+1,right);
            }
            return A;
        }
        
        int partition(int* A, int left, int right)
        {
            int pivot = left-1;
            int index = left;
            while(index <= right)
            {
                if(A[index] <= A[right])
                {
                    ++pivot;
                    int temp = A[index];
                    A[index] = A[pivot];
                    A[pivot]= temp;
                }
                index++;
            }
            return pivot;
        }
    };

     6. 堆排序

     堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。其思路如下:

     a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

     b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

     c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

    参考链接:https://www.cnblogs.com/chengxiao/p/6129630.html

    class HeapSort {
    public:
        void swap(int* A,int i,int j)
        {
            int temp = A[i];
            A[i] = A[j];
            A[j] = temp;
        }
        
        void adjustHeap(int* A, int n, int left, int right)
        {
            int parent = left;
            int maxChild = 2 * parent + 1;
            int value = A[parent];
            
            while(maxChild <= right)
            {
                maxChild = A[maxChild + 1] > A[maxChild] && maxChild < right ? maxChild + 1: maxChild;
                if( value < A[maxChild])
                {
                    A[parent] = A[maxChild];
                    parent = maxChild;
                    maxChild = 2 * parent + 1;
                }
                else
                    break;
            }
            A[parent] = value;
            
        }
        int* heapSort(int* A, int n) {
            // write code here
           for(int i = n/2-1; i>=0; i--)
               adjustHeap(A,n,i,n-1);
            for(int i = n-1; i >0; i--)
            {
                swap(A,i,0);
                adjustHeap(A,n,0,i-1);
            }
            return A;
        }
    };

     7. 希尔排序

      希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

    class ShellSort {
    public:
        int* shellSort(int* A, int n) {
            // write code here
            if(A==nullptr||n<2)
                return A;
            int inc = n/2;
            int index = 0;
            while(inc > 0)
            {
                for(int i = inc; i < n; i++)
                {
                    index = i;
                    while(index >= inc)
                    {
                        if(A[index - inc] > A[index])
                        {
                            int temp = A[index - inc];
                            A[index - inc] = A[index];
                            A[index] = temp;
                            index -= inc;
                        }
                        else
                            break;
                    }
                }
                inc /= 2;
            }
            return A;
        }
    };

     8. 桶排序

    class CountingSort {
    public:
        void max_min(int* A, int n, int& max, int& min)
        {
            max = min = A[0];
            for(int i = 1; i < n; i++)
            {
                if(A[i]<min)
                    min = A[i];
                else if(A[i]>max)
                    max = A[i];
            }
        }
        
        int* countingSort(int* A, int n) {
            // write code here
            if(A == nullptr||n < 2)
                return A;
            int max, min;
            max_min(A,n,max,min);
            int* tong = new int[max - min + 1];
            for (int i = 0;i < max - min + 1;i++)        //清零
                tong[i] = 0;
            for(int i = 0; i < n; i++)                   //计数
                tong[A[i]-min]++;
            int index = 0;
            for(int i = 0; i< max-min+1; i++)
                while(tong[i] > 0)
                {
                    A[index++] = i+min;
                    tong[i]--;
                }
            return A;
        }
    };

      

      

      

  • 相关阅读:
    Linux命令格式与修改文件权限的命令
    Linux 文件基本属性
    Linux 系统目录结构
    Linux 系统启动过程
    Linux在线学习模拟器
    jQuery做的自定义选项卡
    jQuery做的可编辑表格
    海康解码器对接总结(java 版)
    Java线程总结(二)
    Java线程总结(一)
  • 原文地址:https://www.cnblogs.com/linear/p/8448559.html
Copyright © 2011-2022 走看看