1.双向冒泡:
通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。
代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。
写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。
反正我认为这是一段有趣的代码,值得一看。
#include <iostream.h>
void Bubble2Sort(int* pData,int Count)
{
int iTemp;
int left = 1;
int right =Count -1;
int t;
do
{
//正向的部分
for(int i=right;i>=left;i--)
{
if(pData[i]<pData[i-1])
{
iTemp = pData[i];
pData[i] = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
left = t+1;
//反向的部分
for(i=left;i<right+1;i++)
{
if(pData[i]<pData[i-1])
{
iTemp = pData[i];
pData[i] = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
right = t-1;
}while(left<=right);
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
Bubble2Sort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"/n";
}
快速排序
#include <iostream>
using namespace std;
class QuickSort public:
void quick_sort(int* x,int low,int high)
{
int pivotkey;
if(low <high)
{
pivotkey=partion(x,low,high);
quick_sort(x,low,pivotkey-1);
quick_sort(x,pivotkey+1,high);
}
}
int partion(int* x,int low,int high)
{
int pivotkey;
pivotkey=x[low];
while(low <high)
{
while (low <high&&x[high]>=pivotkey)
--high; //还有while循环只执行这一句
x[low]=x[high];
while (low <high&&x[low] <=pivotkey)
++low; //还有while循环只执行这一句
x[high]=x[low];
}
x[low]=pivotkey;
return low;
}
};
int main()
{
int x[10]={52,49,80,36,14,58,61,97,23,65};
QuickSort qs;
qs.quick_sort(x,0,9);
cout <<"排好序的数字序列为:" <<endl;
for (int i=0;i <10;i++)
{
printf("%d ",x[i]);
}
return 0;
}
{
2.SHELL排序
这个排序非常复杂,看了程序就知道了。
首先需要一个递减的步长,这里我们使用的是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[i];
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[i]<<" ";
cout<<"/n";
}
呵呵,程序看起来有些头疼。不过也不是很难,把s==0的块去掉就轻松多了,这里是避免使用0步长造成程序异常而写的代码。这个代码我认为很值得一看。这个算法的得名是因为其发明者的名字D.L.SHELL。依照参考资料上的说法:“由于复杂的数学原因避免使用2的幂次步长,它能降低算法效率。”另外算法的复杂度为n的1.2次幂。同样因为非常复杂并“超出本书讨论范围”的原因(我也不知道过程),我们只有结果了
冒泡排序性能优化版
#include <iostream>
using namespace std;
void maopao(int *list,int n)
{
int i=n,j,temp;
bool exchange;//当数据已经排好时,退出循环
for(i=0;i<n;i++)
{
exchange=false;
for (j=0;j<n-i-1;j++)
{
if (list[j]>list[j+1])
{
temp=list[j];
list[j]=list[j+1];
list[j+1]=temp;
exchange=true;
}
}
if (!exchange)
{
return;
}
}
}
int main()
{
int a[7]={32,43,22,52,2,10,30};
maopao(a,7);
for(int i=0;i<7;i++)
cout<<a[i]<<" ";
return 0;
}
在CSDN的C语言板块看到了有人说Shell排序的问题,所以一起学习了一下,并进行如下总结
shell排序的思想是根据步长由长到短分组,进行排序,直到步长为1为止,属于插入排序的一种。下面用个例子更好的理解一下
无序数列: 32, 43,56,99,34,8,54,76
1.首先设定gap=n/2=4于是分组
32,34 排序 32,34
43, 8 8, 43
56,54 54,56
99,76 76,99
数列变成 32,8,54,76,34,43,56,99
2.gap=gap/2=2 于是分组
32,54,34,56 排序 32,34,54,56
8,76,43,99 8,43,76,99
于是数列变成 32,8,34,43,54,76,56,99
3.gap=gap/2=1于是分组
32,8,34,43,54,76,56,99 排序
8,32,34,43,54,56,76,99
gap=1结束……
相应的C语言代码引用K&R C程序设计一书中给出的代码
void shellsort(int v[], int n)
{
int gap, i, j, temp;
for(gap=n/2;gap>0;gap/=2) //设定步长
for(i=gap;i<n;++i) //在元素间移动为止
for(j=i-gap; j>=0&&v[j]>v[j+gap]; j-=gap){ //比较相距gap的元素,逆序互换
temp=v[j];
v[j]=v[j+gap];
v[j+gap]=temp;
}
}
来自:http://topic.csdn.net/u/20080928/14/4e7a079c-21c4-484b-ab80-3785beccd489.html