常用排序算法:冒泡排序,快速排序,歸并排序,插入排序,堆排序,統(tǒng)計(jì)排序。
冒泡排序偽代碼:
for i = [1,n)
for (j = i; j > 0 ; j--)
if(x[i] > x[j]) swap(i,j)
插入排序偽代碼:
for i = [1,n)
for (j = i; j > 0 && x[j-1] > x[j]; j--)
swap(j-1,j)
原理是,想象自己在摸牌,牌放在桌子上,我們每拿起一張,先將這張牌放在最右邊,然后與手里的牌從右到左的比較,一次一次的向前交換,直到到達(dá)合適的位置。
實(shí)用C++代碼:
//insert_sort.cpp
template<typename RandomAccessIterator>
void insert_sort(RandomAccessIterator first, RandomAccessIterator last)
{
if(first == last) return;
for(RandomAccessIterator i = first+1; i != last; ++i) //拿起桌子上的牌,從first+1開始拿是因?yàn)橹挥幸粡埖脑挘旧砭陀行蛄恕?br /> linear_insert(first, i, value_type(first)); //給拿起來的牌排序,從右往左插入。
}
template<typename RandomAccessIterator>
inline void linear_insert(RandomAccessIterator first, RandomAccessIterator last,
T* )
{
T value = *last;
if(value < *first){ //最右邊的值比最左邊的值還要大,那就把最右邊的牌放在最前面,因此其他的牌依次向后(右邊)移動(dòng)。
std::copy_backward(first, last, first+1); //其他的牌依次向后(右邊)移動(dòng),將第一個(gè)位置留給新牌。
*first = value; //把新的牌放在第一個(gè)位置。
}
else{
unguarded_linear_insert(last, value); //依次線性的
從右往左比較,讓新牌自己去找個(gè)合適的位置。
}
}
template<typename RandomAccessIterator>
inline void unguarded_linear_insert(RandomAccessIterator last, T value)
{
RandomAccessIterator next = last;
--next;
while(value < *next){ //一個(gè)一個(gè)的來比較,如果新牌比較大,就和老的牌換一下位置
*last = *next;
last = next;
--next;
}
*last = value;
/*
//Or we can make it like this:
RandomAccessIterator position = find(last, first, less_than(*last));
swap(value, copy(position, last,position+1) );
*/
}
快速排序偽代碼:
void qsort(lower, uper)
if lower >= uper then
return
middle = lower
for i = [lower+1, uper]
if x[i] < x[l] then
swap(++middle, i)
swap(lower, middle)
qsort(lower, middle-1)
qsort(middle+1, uper)
實(shí)際代碼,之后重新定制了這個(gè)算法,使用雙邊快排:
#include <iostream>
#include <bits/stl_iterator_base_types.h>
#include <algorithm>
template<typename RandomAccessIterator>
void qsort(RandomAccessIterator first, RandomAccessIterator last){
if( first == last ) return;
typename std::iterator_traits<RandomAccessIterator>::value_type tmp = *first;// *(last - 1);
RandomAccessIterator left = first;
RandomAccessIterator right = last;
while(true){
while(*left < tmp) ++left;
--right;
while(*right > tmp) --right;
if(right - left < 1) break;
std::swap(*left, *right);//iter_swap(leftm, right);
++left;
}
//std::swap(*first,*right); 這個(gè)交換可以換得比較穩(wěn)定的時(shí)間復(fù)雜度,但是有些情況下,效率沒有去掉此行高
qsort(first, left);
qsort(right+1, last);
}
int main(){
int x[10] = {5,6,8,4,9,1,3,7,6,33};
for(int i = 0; i < 9999999; ++i)
std::sort(x,x+10); //use time 2.272s
//qsort(x,x+10); //use time 4.072s
std::for_each(x, x+10, [](int tmp){
std::cout<<tmp<<" ";
});
return 0;
}
//程序的執(zhí)行時(shí)間在linux下的測(cè)試方式是time a.out
一個(gè)題,寫一個(gè)函數(shù)將第一個(gè)參數(shù)所有的小寫字母轉(zhuǎn)換成大寫字母,結(jié)果放在第二個(gè)參數(shù)里面。函數(shù)原型為void transfer_up(const char *first, char *second);
輸入限制為a-zA-Z
//單個(gè)字符小寫轉(zhuǎn)換為大寫
char toupper( char c){
return c & 0x5F ;
}
//單個(gè)字符大寫轉(zhuǎn)換為小寫
char tolower( char c) {
// c | 0x60也行,但不太好,因?yàn)?x60會(huì)改變結(jié)果的第7位值,根據(jù)題目意思,改變第6位值為1,而其它位保持不變就夠了。
return c | 0x20 ;
}
完全方案
void transfer_up(const char *first, char *second){
if(*first == '\0' || first == (char*)0 ){
second = 0;
return;
}
do{
if(*first > 'a' && *first < 'z')
*second++ = (*first) &0x5F; //或者static int delta = 'A' - 'a'; *second++ = *first + delta;
}while(*(++first) != '\0');
*second = '\0';
}
那么大寫轉(zhuǎn)小寫也是同樣的道理了。不過是同0x20求與。