排序----插入排序,二路归并排序,堆排序,快速排序

 插入排序:
   默认升序,向已排序的数组中插入新的元素,要求插入后的数组仍然为升序。
方法:
    按照从后往前的顺序将新元素与数组中的元素比较,直到找到第一个小于新元素的
元素,其所在的位置即为新元素的位置。

#include <iostream>
using std::cout;
using std::endl;


class insert
{
public:
    insert(int *arr,const int size);
    ~insert();
    void sort();

private:
    int *vec;
    int len;
};

insert::insert(int *arr, const int size)
{
    if (size > 0)
    {
        vec = new int[size];
        if (NULL != vec)
                                 
        {
           len = size;
           for (int i = 0; i < size; ++i)
              *(vec+i) = *(arr+i);
        }
    }
}
insert::~insert()
{
    if (NULL != vec)
    {
        for (int i = 0; i < len; ++i)
            cout << *(vec+i) << "  ";
        cout << endl;
        delete []vec;
        vec = NULL;
    }
}

void insert::sort()
{
    int key;
    for (int i = 1; i < this->len; ++i)
    {
        int key = vec[i], j = i-1;
        while (vec[j] > key && j >= 0)
        {
            vec[j+1] = vec[j];
            --j;
        }
        vec[j+1] = key;
    }
}

int main()
{
   int arr[10] = {100, 70, -90, 0, 1, -500, 800, -1000, -22, 88};
   int i = 0;
   for (i = 0; i < 10; ++i)
       cout << arr[i] << "   ";
   cout << endl;
   insert ins(arr, 10);
   ins.sort();
   return 0;
}
-----------------------------------------------
二路归并排序

方法:将n个元素分成各含n/2个元素的子序列,用合并排序法对两个子序列递归地排序,
合并两个已排序的子序列以得到排序结果

#include <iostream>
using std::cout;
using std::endl;

void merge(int arr[], int bgn, int mid, int end)
{
     int *left = new int[mid-bgn+1];
     int *right = new int[end-mid];

     if (NULL == left || NULL == right)
        return;

     int i, j, k;
     for (i = bgn, k = 0; i <= mid; ++i)
         *(left+k++) = *(arr+i);
     for (i = mid+1, k = 0; i <= end; ++i)
         *(right+k++) = *(arr+i);

     i = 0, j = 0, k = bgn;
     while (i <= (mid-bgn) && j <= (end-mid-1))
     {
         if (*(left+i) < *(right+j))
              *(arr+k++) = *(left+i++);
         else
              *(arr+k++) = *(right+j++);
     }

     for (;i <= (mid-bgn); ++i)
         *(arr+k++) = *(left+i);
     for (;j <= (end-mid-1); ++j)
         *(arr+k++) = *(right+j);
     cout << "---------- bgn = " << bgn << " , end = " << end  << endl;
     for (int i = bgn; i <= end; ++i)
         cout << arr[i] << "  ";
     cout << endl;
     cout << "--------- end" << endl;
     delete []left;
     left = NULL;
     delete []right;
     right = NULL;
}

void mergesort(int arr[], int bgn, int end)
{
     if (bgn < end)
     {
         int mid = (bgn+end)/2;
         mergesort(arr, bgn, mid);
         mergesort(arr, mid+1, end);
         merge(arr, bgn, mid, end);
     }
}

int main()
{
    int i, arr[] = {5, 2, 4, 7, 1, 3, 2, 6, -9};
    for (i = 0; i < 9; ++i)
        cout << arr[i] << "  ";
    cout << endl;
    mergesort(arr, 0, 8);
    for (i = 0; i < 9; ++i)
        cout << arr[i] << "  ";
    cout << endl;

    return 0;
}
               

 

------------------------------------------------------

/*
堆:若将序列所存储的arr[1,n]看做是一棵完全二叉树的存储结构,
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字
堆排序:
1.将要排序的数组创建为一个大根堆。大根堆的堆顶元素就是这个堆中最大的元素。
2.将大根堆的堆顶元素和无序区最后一个元素交换,并将无序区最后一个位置加入有序区,
  然后将新的无序区调整为大根堆。重复操作,无序区在递减,有序区在递增。
*/
#include <iostream>
using std::cout;
using std::endl;
#define LEFT(i) ((i<<1)+1)
#define RIGHT(i) ((i<<1)+2)

// 为了始终保持大根堆的属性,对堆中的第i个元素进行调整
void max_heapify(int arr[], int i, int heapsize)
{
     int l = LEFT(i);
     int r = RIGHT(i);
     // 找出i节点及其左右孩子的最大值的index
     int largest = i;
     if (l < heapsize)
     {
           if (arr[l] >= arr[i])
                largest = l;
           else
                largest = i;
     }
     if (r < heapsize && arr[r] >= arr[largest])
          largest = r;
     // 如果i节点最大,则不需要调整,否则交换i节点与其左右孩子中的较大者,
     // 在其较大孩子所对应的子树中继续对i节点进行调整,直到满足大根堆的属性
     if (largest != i)
     {
          int tmp = arr[largest];
          arr[largest] = arr[i];
          arr[i] = tmp;
          max_heapify(arr, largest, heapsize);
     }
}

// 由于大根堆是完全二叉树,所以建堆时,只需要调整非叶子节点
void build_max_heap(int arr[], int len)
{
     for (int i = (len-1)>>1; i >= 0; --i)
          max_heapify(arr, i, len);
}

// 堆排序:首先建立大根堆,由于大根堆的最大节点总是为arr[0]
// 将arr[0]与当前大根堆最后节点交换,这样就可以获取当前堆的
// 最大节点,减去当前堆的最大节点,继续按照大根堆的属性调整
// 当前剩余的节点
void heapsort(int arr[], int len)
{
      int tmp;
      build_max_heap(arr, len);
      for (int i = len-1; i > 0; --i)
      {
           --len;
           tmp = arr[0];
           arr[0] = arr[i];
           arr[i] = tmp;
           max_heapify(arr, 0, len);
      }
}

int main()
{
      int i, arr[10] = {4, 1, 3 ,2, 16, 9, 10, 14, 8, 7};
      for (i = 0; i < 10; ++i)
           cout << arr[i] << "  ";
      cout << endl;
      heapsort(arr, 10);
      for (i = 0; i < 10; ++i)
           cout << arr[i] << "  ";
      cout << endl;

      return 0;
}

 ----------------------------------------------

/*
堆:若将序列所存储的arr[1,n]看做是一棵完全二叉树的存储结构,
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字
最大优先队列的一个应用是在一个分时计算机上进行作业调度
*/
#include <iostream>
using std::cout;
using std::endl;
#define LEFT(i) ((i<<1)+1)
#define RIGHT(i) ((i<<1)+2)
#define PARENT(i) ((i-1)>>1)

// 为了始终保持大根堆的属性,对堆中的第i个元素进行调整
void max_heapify(int arr[], int i, int heapsize)
{
     int l = LEFT(i);
     int r = RIGHT(i);
     // 找出i节点及其左右孩子的最大值的index
     int largest = i;
     if (l < heapsize)
     {
          if (arr[l] >= arr[i])
               largest = l;
         else
               largest = i;
     }
     if (r < heapsize && arr[r] >= arr[largest])
     largest = r;
     // 如果i节点最大,则不需要调整,否则交换i节点与其左右孩子中的较大者,
     // 在其较大孩子所对应的子树中继续对i节点进行调整,直到满足大根堆的属性
     if (largest != i)
     {
           int tmp = arr[largest];
           arr[largest] = arr[i];
           arr[i] = tmp;
           max_heapify(arr, largest, heapsize);
      }
}

// 由于大根堆是完全二叉树,所以建堆时,只需要调整非叶子节点
void build_max_heap(int arr[], int len)
{
      for (int i = (len-1)>>1; i >= 0; --i)
           max_heapify(arr, i, len);
}

// 返回大根堆中的最大节点
int heap_maximum(int arr[])
{
       return arr[0];
}

// 去除并返回大根堆中的最大节点
int heap_extract_max(int arr[], int len)
{
     if (len < 1)
          return -1;
     int tmp = arr[0];
     arr[0] = arr[len-1];
     --len;
     max_heapify(arr, 0, len);
     return tmp;
}

// 将节点x的值提升到key,在key>arr[x]的前提下
bool heap_increase_key(int arr[], int x, int key)
{
     if (arr[x] > key)
         return false;
     arr[x] = key;
     int tmp;
     while (x > 0 && arr[PARENT(x)] < arr[x])
     {
           tmp = arr[PARENT(x)];
           arr[PARENT(x)] = arr[x];
           arr[x] = tmp;
           x = PARENT(x);
      }
      return true;
}

// 插入元素key
void max_heap_insert(int arr[], int len, int key)
{
      arr[len] = -1;
      ++len;
      heap_increase_key(arr, len-1, key);
}

int main()
{
      int i, arr[20] = {4, 1, 3 ,2, 16, 9, 10, 14, 8, 7};
      for (i = 0; i < 10; ++i)
           cout << arr[i] << "  ";
      cout << endl;
      build_max_heap(arr, 10);
      for (i = 0; i < 10; ++i)
           cout << arr[i] << "  ";
      cout << endl;
/*
      cout << "heap_extract_max " << heap_extract_max(arr, 10) << endl;
      for (i = 0; i < 9; ++i)
            cout << arr[i] << "  ";
      cout << endl;
*/
      max_heap_insert(arr, 10, 20);
      for (i = 0; i < 11; ++i)
            cout << arr[i] << "  ";
      cout << endl;
 
      return 0;
}

 

------------------------------------------------------------------------------
/*
 快速排序:选择一个key,从左边查找第一个比key大的元素与此交换,
然后,从右边查找第一个比key小的元素与此交换,不断重复这个过程;
最终,使其左边的元素均小于key,其右边的元素均大于key
*/
#include <iostream>
using std::cout;
using std::endl;

int partition(int arr[], int p, int r)
{
        int key = arr[r], i = p, j = r;
        while (i < j)
        {
                while (i < j && arr[i] < key) //find the first element great than key from left
                        ++i;

                if (i < j)                    // found
                        arr[j--] = arr[i];

                while (i < j && arr[j] > key) //find the first element which less than key from right
                        --j;

                if (i < j)                    // found
                        arr[i++] = arr[j];
        }
        arr[i] = key;
        return i;
}

void qsort(int arr[], int p, int r)
{
        int tmp = 0;
        if (p < r)
        {  
                tmp = partition(arr, p, r);
                qsort(arr, p, tmp-1);
                qsort(arr, tmp+1, r);
        }
}

int main()
{
        int arr[8] = {2, 8, 7, 1, 3, 5, 6, 4};
        qsort(arr, 0 , 7);
        for (int i = 0; i < 8; ++i)
                cout << arr[i] << "  ";
        cout << endl;
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值