排序算法备份

来源:互联网 发布:在文都上班怎么样知乎 编辑:程序博客网 时间:2024/05/19 17:05

若干基本内排序算法(C语言)的备份,闲时来看看,以防忘记。

1.插入排序

void InsertSort(elemtype x[],int n)

{

    int i,j;

    elemtype temp;

   

    for(i=0;i<n-1;i++)

    {

        temp=x[i+1];

        j=i;

        while(j>-1&&temp.key<x[j].key)

        {

            x[j+1]=x[j];

            j--;

        }

        x[j+1]=temp;

    }

}

 

2.选择排序

void SelectSort(elemtype x[],int n)

{

    int i,j,small;

    elemtype temp;

    for(i=0;i<n-1;i++)

    {

        small=i;

        for(j=i+1;j<n;j++)

        if(x[j].key<x[small].key) small=j;

       

        if(small!=i)

        {

            temp=x[i];

            x[i]=x[small];

            x[small]=temp;

        }

    }

}

 

3.交换排序

void BubbleSort(elemtype x[],int n)

{

    int i,j,flag=1;

    elemtype temp;

    for(i=0;i<n&&flag==1;i++)

    {

        flag=0;

        for(j=0;j<n-1;j++)

        {

            if(x[j].key>x[j+1].key)

            {

                flag=1;

                temp=x[j];

                x[j]=x[j+1];

                x[j+1]=temp;

            }

        }

    }

}

 

4.快速排序

void QuickSort(elemtype x[],int low,int high)

{

    int i,j;

    elemtype temp;

 

    i=low;

    j=high;

    temp=x[low];

 

    while(i<j)

    {

 

        //在序列的右端扫描

        while(i<j&&temp.key<=x[j].key)  j--;

        if(i<j)

        {

            x[i]=x[j];

            i++;

        }

 

        //在序列的左端扫描

        while(i<j&&x[i].key<temp.key)  i++;

        if(i<j)

        {

            x[j]=x[i];

            j--

        }

       

    }

    //确定了x[low]在有序序列中的最终位置

      x[i]=temp;//temp==x[low]

 

    //对子序列进行快速排序

    if(low<i-1)  QuickSort(x,low,i-1);

    if(j+1<high)  QuickSort(x,j+1,high);

 

}

 

5.希尔排序


这个排序非常复杂,看了程序就知道了。

  首先需要一个递减的步长,这里我们使用的是9、5、3、1(最后的步长必须是1)。

  工作原理是首先对相隔9-1个元素的所有内容排序,然后再使用同样的方法对相隔5-1个元素的排序

  以次类推。

  #include <iostream.h>

  void ShellSort(int* pData,int Count)

  {

  int step[4];

  step[0] = 9;

  step[1] = 5;

  step[2] = 3;

  step[3] = 1;

  int iTemp;

  int k,s,w;

  for(int i=0;i<4;i++)

  {

  k = step;

  s = -k;

  for(int j=k;j<Count;j++)

  {

  iTemp = pData[j];

  w = j-k;//求上step个元素的下标

  if(s ==0)

  {

  s = -k;

  s++;

  pData[s] = iTemp;

  }

  while((iTemp<pData[w]) && (w>=0) && (w<=Count))

  {

  pData[w+k] = pData[w];

  w = w-k;

  }

  pData[w+k] = iTemp;

  }

  }

  }

  void main()

  {

  int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};

  ShellSort(data,12);

  for (int i=0;i<12;i++)

  cout<<data<<" ";

  cout<<"\n";

  }

  呵呵,程序看起来有些头疼。不过也不是很难,把s==0的块去掉就轻松多了,这里是避免使用0

  步长造成程序异常而写的代码。这个代码我认为很值得一看。

  这个算法的得名是因为其发明者的名字D.L.SHELL。依照参考资料上的说法:“由于复杂的数学原因

  避免使用2的幂次步长,它能降低算法效率。”另外算法的复杂度为n的1.2次幂。同样因为非常复杂并

  “超出本书讨论范围”的原因(我也不知道过程),我们只有结果了。

 

 

 

6.堆排序 


  // array是待调整的堆数组,i是待调整的数组元素的位置,length是数组的长度

  void HeapAdjust(int array[], int i, int nLength)//本函数功能是:根据数组array构建大根堆

  {

  int nChild;

  int nTemp;

  for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild)

  {

  // 子结点的位置=2*(父结点位置)+ 1

  nChild = 2 * i + 1;

  // 得到子结点中较大的结点

  if (nChild < nLength - 1 && array[nChild + 1] > array[nChild])

  ++nChild;

  // 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点

  if (nTemp < array[nChild])

  {

  array[i]= array[nChild];

  }

  else // 否则退出循环

  {

  break;

  }

  // 最后把需要调整的元素值放到合适的位置

  array[nChild]= nTemp;

  }

  }

  // 堆排序算法

  void HeapSort(int array[], int length)

  {

  // 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素

  for (int i = length / 2 - 1; i >= 0; --i)

  {

  HeapAdjust(array, i, length);

  }

  // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素

  for (int i = length - 1; i > 0; --i)

  {

  // 把第一个元素和当前的最后一个元素交换,

  // 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的

  Swap(&array[0], &array[i]);

  // 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值

  HeapAdjust(array, 0, i);

  }

  }  


 

原创粉丝点击