堆排序是另外一種常用的遞迴排序。因為堆排序有著優秀的排序效能,所以在軟體設計中也經常使用。堆排序有著屬於自己的特殊性質,和二叉平衡樹基本是一致的。打乙個比方說,處於大堆中的每乙個資料都必須滿足這樣乙個特性:
(1)每乙個array[n] 不小於array[2*n]
(2)每乙個array[n]不小於array[2 * n + 1]
構建這樣乙個堆只是基礎,後面我們需要每次從堆的頂部拿掉乙個資料,不斷調整堆,直到這個陣列變成有序陣列為主。所以詳細的堆排序演算法應該是這樣的:
1)構建大堆,使得堆中的每乙個資料都滿足上面提到的性質
2)將堆的第乙個資料和堆的最後乙個資料進行互換,然後重新調整堆,直到堆重新平衡為止
3)重複2)的過程,直到整個陣列有序。
上面的描述過程很簡單,那麼實踐操作是怎麼樣的呢?
a)對入參進行判斷
void heap_sort(int array, int length)
b)構建大堆和調整大堆
void _heap_sort(int array, int length)
}
c)構建大堆的細節操作部分
void set_sorted_value(int array, int length)
}void construct_big_heap(int array, int length)
}
d)大堆迭代調整
void reconstruct_heap(int array, int index, int length)
if(-1 != (swap = adjust_normal_position(array, index)))
}
e)對單分支節點和滿分支節點分別處理
int adjust_normal_position(int array, int index)
else
}elseelse
} if(swap == left) else
return swap;
}status adjust_leaf_position(int array, int index)
f)堆排序演算法介紹完畢,建立測試用例驗證
static void test1()
; heap_sort(array, sizeof(array)/sizeof(int));
}static void test2()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(1 == array[0]);
assert(2 == array[1]);
}static void test3()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(1 == array[0]);
assert(2 == array[1]);
assert(3 == array[2]);
}static void test4()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(1 == array[0]);
assert(2 == array[1]);
assert(3 == array[2]);
}static void test5()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(1 == array[0]);
assert(3 == array[1]);
assert(4 == array[2]);
assert(5 == array[3]);
}static void test6()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(2 == array[0]);
assert(3 == array[1]);
assert(6 == array[2]);
assert(7 == array[3]);
assert(8 == array[4]);
}static void test7()
; heap_sort(array, sizeof(array)/sizeof(int));
assert(1 == array[0]);
assert(2 == array[1]);
assert(3 == array[2]);
assert(4 == array[3]);
assert(5 == array[4]);
assert(6 == array[5]);
assert(7 == array[6]);
assert(8 == array[7]);
assert(9 == array[8]);
}
【預告: 下面的部落格介紹一些常用的資料結構】
一步一步寫演算法(之快速排序)
快速排序是程式設計中經常使用到的一種排序方法。可是很多朋友對快速排序有畏難情緒,認為快速排序使用到了遞迴,是一種非常複雜的程式,其實未必如此。只要我們使用好了方法,就可以自己實現快速排序。首先,我們複習一下,快速排序的基本步驟是什麼 1 判斷輸入引數的合法性 2 把陣列的第乙個資料作為比較的原點,比...
一步一步寫演算法 之快速排序
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!快速排序是程式設計中經常使用到的一種排序方法。可是很多朋友對快速排序有畏難情緒,認為快速排序使用到了遞迴,是一種非常複雜的程式,其實未必如此。只要我們使用好了方法,就可以自己實現快速排序。首先,我們複習一下,快速排序的基本步驟是什麼 1 判斷輸入引...
一步一步寫演算法(之 A 演算法)
在前面的部落格當中,其實我們已經討論過尋路的演算法。不過,當時的示例圖中,可選的路徑是唯一的。我們挑選乙個演算法,就是說要把這個唯一的路徑選出來,怎麼選呢?當時我們就是採用窮盡遞迴的演算法。然而,今天的情形有點不太一樣了。在什麼地方呢?那就是今天的路徑有n條,這條路徑都可以達到目的地,然而我們在挑選...