1.交换
交换,就是根据序列中两个元素关键字的比较结果对换两个记录在序列中的位置。
2.冒泡排序
冒泡排序的主要思想是:假设待排序表长为n,从前往后两两比较相邻元素的值,若为逆序,则交换他们,直到序列比较完成,称之为一趟冒泡,其结果是最大的元素交换到待排序序列的末尾。下一趟冒泡时,最末尾元素不再参与比较,待排序序列减少一个元素。每趟冒泡都把序列中最大元素放在了序列的最终位置,这样最多做n-1次冒泡就可以把元素排好序。
代码如下
void bubblesort(int A[],int len)
{
for(int i = 1;i <= len-1;i++)//最多n-1趟冒泡
{
bool flag = false;//设置标志位,标识本趟冒泡是否交换过
for(int j=0;j<len-i;j++)//每冒泡一趟减少一个元素
{
if(A[j]>A[j+1])
{
int temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
flag = true;//若交换过,置flag为true
}
}
if(flag == false) return;//若交换过,则表示表已经有序,直接结束
}
}
3.快速排序
快速排序是冒泡排序的改进,冒泡排序每次把一个元素放在最终位置上(序列最后或者最前面),快速排序每次也确定一个元素的最终位置,只不过通常这个元素位于待排序列的中间,从而将一个序列分成两部分,再分别对这两个子序列进行递归划分。
快速排序的主要思想是:在待排序表L[1....n]中任取一个元素privot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1..k-1]、L[k+1...n],使得L[1..k-1]所有元素小于等于privot,L[k+1...n]所有元素大于privot,则privot放在了其最终位置L[k]上,这个过程称为一趟快速排序。之后,分别递归地对两个子表重复上述过程,直至每部分只含一个元素或者空位置,即所有元素放在了其最终位置上。
下面是对一个典型子数组A[p,..,r]进行快速排序的三步分治过程:
(1)分解:数组A[p,..,r]被划分为两个子数组(可能为空)A[p,..,q-1]、A[q+1,..,r],使得A[p,..,q-1]的每一个元素都小于等于A[q],A[q+1,..,r]大于等于A[q]。其中下标q也是划分过程的一部分。
(2)解决:通过递归调用快速排序,对子数组A[p,..,q-1]、A[q+1,..,r]进行排序。
(3)合并:因为子数组是原址排序的,所以不要合并操作,数组已经有序了。
以下是快速排序的伪代码:
<strong>quicksort(A,p,r)</strong>
if p < r
q = partion(A,p,r);
quicksort(A,p,q-1);
quicksort(A,q+1,r);</span>
以下是patrion的过程,其实现了对子数组A[p,...,r]的原址重排:
<span style="font-size:14px;">partion(A,p,r)
i = p-1;
j = p;
x = A[r];
for j = p:r-1
if A[j] <= x
i = i + 1;
exchange(A[i],A[j]);
exchange(A[i+1],A[r]);
return i+1;
上述过程满足以下循环不变量:
(1)若p<=k<=i,A[k]<=x;
(2)若i+1<=k<=j-1,A[k]>x;
(3)若p==k,A[k]==x;
以下是实现代码:
int partion(int A[],int p,int r)
{
int i = p - 1;//p到i的元素小于等于A[r];
int j = p;//i+1到j-1的元素大于A[r];
int x = A[r];
for (; j <= r-1;j++)
if(A[j] <= x)
{
i = i + 1;
int temp = A[i];A[i] = A[j];A[j] = temp; //exchange(A[i],A[j]);
}
int temp = A[i+1];A[i+1] = A[r];A[r] = temp;//exchange(A[i+1],A[r]);
return i+1;
}
void quicksort(int A[],int p,int r)
{
if(p < r)
{
int q = partion(A,p,r);
quicksort(A,p,q-1);
quicksort(A,q+1,r);
}
}