8种经典排序算法总结

1.二分查找

代码:
int binarySearch(int arr[],int l,int r,int x)
{
    while(l <= r)
    {
        int m = l + (r-1)/2;//为了防止(l+r溢出)
        if(arr[m] == x)
            return m;
        if(arr[m] < x)
            l = m + 1;
        else
            r = m - 1;
    }
    return -1;
}

问题扩展1:给定一个有序的数组,用最少的比较次数找出给定的元素。
代码:
int binarySearch(int arr[],int l,int r,int x)//r应该初始化为arr.length
{
    int m;
    while(r - l > l)
    {
        m = l + (r-l)/2;
        if(arr[m] <= x)
            l = m;
        else
            r = m;
    }
    if(arr[l] == x)
        return l;
    else
        return -1;
}

问题扩展2:Given an array of N distinct integers, find floor value of input ‘key’. Say, A = {-1, 2, 3, 5, 6, 8, 9, 10} and key = 7, we should return 6 as outcome.
代码:
int binarySearch(int arr[],int l,int r,int x)
{
    int m;
    while(r - l > l)
    {
        m = l + (r-l)/2;
        if(arr[m] <= x)
            l = m;
        else
            r = m;
    }
        return arr[l];
}

int floor(int arr[],int size,int x)
{
     if(x < arr[0])
          return -1;
     return binarySearch(arr,0,size,x);//注意,r初始化为size
}

问题扩展3:Given a sorted array with possible duplicate elements. Find number of occurrences of input ‘key’ in log N time.
代码:
int getRightPosition(int A[],int l,int r,int key)
{
     int m;
     while(r - l > 1)
     {
          m = l + (r - l)/2;
          if(A[m] <= key)
               l = m;
          else
               r = m;
     }
     return 1;
}

int getLeftPosition(int A[],int l,int r,int key)
{
     int m;
     while(r - l > 1)
     {
          m = l + (r - l)/2;
          if(A[m] >= key)
               r = m;
          else
               l = m;
     }
     return r;
}

int CountOccurances(int A[],int size,int key)
{
     int left = getLeftPosition(A,-1,size-1,key);
     int rigth = getRightPosition(A,0,size,key);
     if(A[left] == key && key == A[right])
          return right-right+1;
     else
          return 0;
}


2.选择排序

技术分享
代码实现:
void selectionSort(int arr[],int n)
{
    int i,j,min_index;
    for(i = 0;i < n;i++)
    {
        min_index = i;
        for(j = i;j < n;j++)
            if(arr[j] < arr[min_index])
                min_index = j;
        swap(&arr[i],&arr[min_index]);
    }
}
时间复杂度:O(n*n)
空间复杂度:O(1)


3.冒泡排序

代码:
void bubbleSort(int arr[],int n)
{
    int i,j;
    for(i = 0;i < n;i++)
        for(j = 0;j < n-i-1;j++)
    {
        if(arr[j] > arr[j+1])
            swap(&arr[j],&arr[j+1]);
    }
}
时间复杂度:O(n*n)
空间复杂度:O(1)


4.插入排序

代码:
void insertionSort(int arr[],int n)
{
    int i,key,j;
    for(i = 1;i < n;i++)
    {
        key = arr[i];
        j = i - 1;
        while(j >= 0 && arr[j] > key)
        {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}
时间复杂度:O(n*n)
空间复杂度:O(1)


5.归并排序

技术分享
代码:
void merge(int array[],int l,int m,int r)//将两个有序的数组合并
{
    int n1 = m - l + 1;
    int n2 = r - m;
    int temp1[n1];
    int temp2[n2];
    int i,j,k;
    for(i = 0;i < n1;i++)
        temp1[i] = array[i+l];
    for(j = 0;j < n2;j++)
        temp2[j] = array[m+1+j];
    i = 0;
    j = 0;
    k = l;
    while(i < n1 && j < n2)
    {
        if(temp1[i] < temp2[j])
        {
            array[k] = temp1[i];
            i++;
            k++;
        }
        else
        {
            array[k] = temp2[j];
            j++;
            k++;
        }
    }
    while(i < n1)
    {
        array[k] = temp1[i];
        i++;
        k++;
    }
    while(j < n2)
    {
        array[k] = temp2[j];
        j++;
        k++;
    }
}

void mergeSort(int array[],int l,int r)
{
    if(r - l > 0)
    {
        int m = l+(r-l)/2;
        mergeSort(array,l,m);
        mergeSort(array,m+1,r);
        merge(array,l,m,r);
    }
}
时间复杂度:O(nlg(n))
空间复杂度:O(n)

6.堆排序

思路:
Heap Sort Algorithm for sorting in increasing order:
1. Build a max heap from the input data.
2. At this point, the largest item is stored at the root of the heap. Replace it with the last item of the heap followed by reducing the size of heap by 1. Finally, heapify the root of tree.
3. Repeat above steps until size of heap is greater than 1

代码:
void maxHeapify(struct MaxHeap * maxHeap,int index)
{
    int left = index * 2 + 1;//左子节点的下标
    int right = index * 2 + 2;//右子节点的下标
    int maxIndex = index;
    if(left < maxHeap->size && maxHeap->array[left] > maxHeap->array[index])
        maxIndex = left;
    if(right < maxHeap->size && maxHeap->array[right] > maxHeap->array[maxIndex])
        maxIndex = right;
    if(maxIndex != index)
    {
        swap(&maxHeap->array[maxIndex],&maxHeap->array[index]);
        maxHeapify(maxHeap,maxIndex);
    }
}

struct MaxHeap * createAndBuildHeap(int * arr,int n)
{
    int i;
    struct MaxHeap * maxHeap = (struct MaxHeap*)malloc(sizeof(struct MaxHeap));
    maxHeap->size = n;
    maxHeap->array = arr;
    for(i = (maxHeap->size/2)-1;i >= 0;i--)//从下标最大的父节点开始heapify操作
        maxHeapify(maxHeap,i);
    return maxHeap;
}

void headpSort(int arr[],int n)
{
    struct MaxHeap * maxHeap = createAndBuildHeap(arr,n);
    while(maxHeap->size > 1)
    {
        swap(&maxHeap->array[0],&maxHeap->array[maxHeap->size-1]);
        maxHeap->size--;
        maxHeapify(maxHeap,0);
    }
}

7.快速排序

思路:每次根据比数组中最后一个元素大还是小将数组分为两个部分,然后递归地对这两个部分运用快排。
代码:
int partition(int array[],int l,int h)
{
    int i = l - 1;
    int target = array[h];
    int j;
    for(j = l;j <= h-1;j++)
    {
        if(array[j] <= target)
        {
            i++;
            swap(&array[i],&array[j]);
        }
    }
    swap(&array[i+1],&array[h]);
    return i+1;
}

void quickSort(int arr[],int l,int h)
{
    if(h > l)
    {
        int pos = partition(arr,l,h);
        quickSort(arr,l,pos-1);
        quickSort(arr,pos+1,h);
    }
}
时间复杂度:O(nlg(n))

8.希尔排序

代码:
void shellSort(int arr[],int n)
{
    int gap,i,j,temp;
    for(gap = n/2;gap > 0;gap = gap/2)
    {
        for(i = gap;i < n;i++)
        {
            temp = arr[i];
            for(j = i;j >= gap && arr[j - gap] > temp;j = j - gap)
                arr[j] = arr[j - gap];//插入排序
            arr[j] = temp;
        }
    }
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。