排序算法

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;
    }
};

  

  

  

原文地址:https://www.cnblogs.com/linear/p/8448559.html