相信大家對氣泡排序一定不陌生吧,作為一種經典的排序方法,它的基本思想是:(以公升序為例)將相鄰的兩個數進行比較,若前乙個數比後乙個數大,則交換它們的順序,這樣一趟下來,最大的數就跑到了最後一位,的二趟還是一樣的方法,最大的數不參與交換,這樣進行n-1趟後,我們就實現了排序;
void
bubblesort
(int
*dest,
int sz)}}
}
但我們說這樣的氣泡排序只能實現整形排序,我現在想讓它在遇到字元型,短整型,浮點型,甚至結構體,都能夠正常的工作,實現乙個通用的氣泡排序,正好庫函式裡有乙個qsort()也是通用的,我們先來看看它的結構是甚麼樣的吧:
我們看到,qsort為傳入的運算元組定義的void*型,這中型別的指標可以存放任何型別資料的位址,但卻無法直接取出,需要將指標進行強制型別轉換後才可以,size_t num是陣列的元素的個數,這與上文的一般氣泡排序的使用方式相同,第三個width則是每個元素的大小,我們無法直接告訴函式目標陣列的型別,只能退而求其次,傳入這個型別的大小,這決定指標的定址步長,得到正確的資料,最後乙個引數,是乙個留給使用者定義的比較函式指標,沒有人會比使用者更清楚要比較什麼樣的資料了,所以函式的使用者需要按照這個函式指標型別封裝乙個返回值為整形,引數為const void*的兩個要比較的元素;
我們的發現氣泡排序的核心在於它如何判斷dest[j]和dest[j+1]的大小,我們仿照qsort,將目標陣列的首元素指標轉化為void*型,假設現在需要判斷整形陣列,我們可以將這個位址強制轉換成char*,然後又根據width來制定指標的步長,這樣就可以把任何型別的資料提取出來
(
char
*)basic+j*width,
(char
*)basic+
(j+1
)*width
這就是dest[j]和dest[j +
1]
然後傳參給使用者自定義的比較函式,如果返回1則表明dest[j]>dest[j + 1],需要交換,非1的話則不用交換
我們這裡又封裝交換函式,這裡直接按位元組交換,只需要將中間變數型別定義成位元組就行:
void
swap
(char
*elem1,
char
*elem2,
unsigned
int width)
//按位元組交換!這樣可以不用判斷到底是什麼型別的資料
}
最後是完整的**,這裡為了測試我定義了三個比較函式,但實際情況下,根據呼叫者的需要只用寫乙個比較函式就行:
//模擬庫函式qsort實現通用氣泡排序
#define _crt_secure_no_warnings 1
#include
#include
#include
struct student
;void
bubblesort
(int
*dest,
int sz)
//只針對int型資料的一般氣泡排序}}
}int
compare_char
(const
void
*elem1,
const
void
*elem2)
//需要使用者自己定義
intcompare_int
(const
void
*elem1,
const
void
*elem2)
//需要使用者自己定義
intcompare_struct
(const
void
*elem1,
const
void
*elem2)
//需要使用者自己定義
void
swap
(char
*elem1,
char
*elem2,
unsigned
int width)
//按位元組交換!這樣可以不用判斷到底是什麼型別的資料
}void
common_bubblesort
(void
*basic,
int sz,
unsigned
int width,
int(
*cmp)
(const
void
*elem1,
const
void
*elem2)
)//大體框架相似於氣泡排序不同之處在於判斷交換的條件}}
}int
main()
//分別使用整形,字元,和結構體進行測試,,
};int arr_int=
;char arr_char=
;int sz_int =
sizeof
(arr_int)
/sizeof
(arr_int[0]
);int sz_char =
sizeof
(arr_char)
/sizeof
(arr_char[0]
);int sz_struct =
sizeof
(init)
/sizeof
(init[0]
);unsigned
int width_int =
sizeof
(int);
unsigned
int width_char =
sizeof
(char);
unsigned
int width_struct=
sizeof
(struct student)
;//bubblesort(arr, sz);
common_bubblesort
(arr_char, sz_char, width_char, compare_char)
;for
(int i =
0; i < sz_char; i++
)printf
("\n");
system
("pause");
return0;
}
模擬實現qsort函式
上節提到qsort函式的原型,今天我們就來模擬下它 首先是qsort函式的主體部分,主要還是迴圈,判斷比較,較困難的是型別的轉化,我們希望可以知道每次訪問的位元組數,即將初始位址轉化為字元指標,即每次解引用可訪問乙個位元組,而再加上j width就可以知道訪問第幾個元素,這樣就可以方便的比較了。vo...
模擬實現qsort函式
模擬實現qsort函式 qsort 的函式原型是 void qsort void base,size t num,size t width,int cdecl compare const void const void qsort 即,quicksort 主要根據你給的比較條件給乙個快速排序,主要是...
C庫函式的模擬實現
1.模擬實現strlen define crt secure no warnings 1 include include size t my strlen const char str return count int main 2.模擬實現strcpy define crt secure no w...