希尔排序
基本思想
计算方法
程序实现
{
int temp;
int h = 3;
while (h > 0)
{
int inner;
for (int outer = h; outer < list.Count; outer++)
{
temp=(int)list[outer];
inner=outer;
while ((inner - h) > -1 && (int)list[inner - h] >= temp)
{
list[inner] = list[inner - h];
inner -= h;
}
list[inner] = temp;
}
h = (h - 1)%3;
}
}
归并排序
算法思想
①分解:将当前区间一分为二,即求分裂点
![](http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu84.gif)
②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
递归的终结条件:子区间长度为1(一个记录自然有序)。
算法过程
算法MergeSortDC的执行过程如下图所示的递归树。
算法程序
public void sort()
{
int[] temp = new int[list.Count];
RecSort(temp,0,list.Count-1);
}
private void RecSort(int[] temp, int lbound, int ubound)
{
if (lbound == ubound)
{
return;
}
else
{
int mid = (int)(lbound + ubound) / 2;
RecSort(temp,lbound,mid);
RecSort(temp,mid+1,ubound);
Merge(temp,lbound,(mid+1),ubound);
}
}
private void Merge(int[] temp, int lbound, int highp, int ubound)
{
int low = lbound;
int mid = highp - 1;
int j=0;
int n = (ubound - low) + 1;
while((lbound<=mid)&&(highp<=ubound))
{
if ((int)list[lbound] < (int)list[highp])
{
temp[j] = (int)list[lbound];
j++;
lbound++;
}
else
{
temp[j] = (int)list[highp];
j++;
highp++;
}
}
while (lbound <= mid)
{
temp[j] = (int)list[lbound];
j++;
lbound++;
}
while (highp <= ubound)
{
temp[j] = (int)list[highp];
j++;
highp++;
}
for (int i = 0; i < n; i++)
{
list[low + i] = temp[i];
}
}
堆排序
算法思想
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
算法过程
给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。首先根据该数组元素构建一个完全二叉树:
算法程序
{
nodes=new Node[list.Count];
int num=list.Count;
for (int i = 0; i < list.Count; i++)
{
InsertArray(i,(int)list[i]);
}
Console.WriteLine();
for (int i = (int)(num / 2) - 1; i >= 0; i--)
{
shifDown(i);
}
for (int i = num - 1; i >= 0; i--)
{
Node bigNode = Remove();
Insert(i, bigNode);
}
Display();
}
private void InsertArray(int i, int p)
{
nodes[i] = new Node(p);
currSize++;
}
private void Display()
{
Console.WriteLine();
for (int i = 0; i < nodes.Length; i++)
{
Console.Write(nodes[i].data+" ");
}
}
private Node Remove()
{
Node fnode=nodes[0];
currSize--;
nodes[0] = nodes[currSize];
shifDown(0);
return fnode;
}
private void shifDown(int index)
{
Node node = nodes[index];
int largeChild;
while (index < (int)((currSize) / 2))
{
int rightChild = index * 2 + 2;
int leftChild = index * 2 + 1;
if ((rightChild < currSize) && (nodes[leftChild].data < nodes[rightChild].data))
{
largeChild = rightChild;
}
else
{
largeChild = leftChild;
}
if (node.data > nodes[largeChild].data)
{
break;
}
nodes[index] = nodes[largeChild];
index = largeChild;
}
nodes[index] = node;
}
private void Insert(int i, Node p)
{
nodes[i] = p;
}
快速排序
算法思想
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
算法步骤
87 | 91 | 65 | 72 | 84 | 99 | 89 |
87 | 91 | 65 | 72 | 84 | 99 | 89 |
87 | 84 | 65 | 72 | 95 | 99 | 89 |
87 | 84 | 65 | 72 | 95 | 99 | 89 |
87 | 84 | 65 | 72 | 95 | 99 | 89 |
72 | 84 | 65 | 87 | 95 | 99 | 89 |