希爾排序
基本思想
計算方法
程序實現
{
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;
}
}
歸併排序
算法思想
①分解:將當前區間一分爲二,即求分裂點
②求解:遞歸地對兩個子區間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 |