C語言排序函式和二分查詢呼叫方法
阿新 • • 發佈:2019-01-05
程式設計時經常遇到對陣列排序或在一個數組中查詢數字的情況,C庫<stdio.h>中提供了簡便的呼叫方法,將排序演算法封裝成通用的排序函式;
排序函式qsort
void qsort(
void *base,
size_t n,
size_t size,
int (*compar)(const void *, const void *)
);
在使用時,使用者需要自己編寫一個判斷兩個數(不僅限於數字)比較大小的方法;
比如簡單的判斷兩個數字的大小:
int num_comp(const int *a,const int *b) { if(*a==*b) return 0; return *a>*b?1:-1; }
注意函式的格式是不能變的,且第一個引數>第二個引數,需要返回一個正數.
在呼叫時,該如何呼叫呢?
如果有一個數組int num[100];
裡面是100個未排序的數字,要將這個陣列按升序排列;
呼叫qsort函式:
qsort(num,100,sizeof(int),(int (*)(const void *,const void *))num_comp);
說明一下這裡的引數,
第一個引數num是陣列名;
第二個引數100是說這個要排序的陣列大小num[0]到num[100-1];
第三個引數是排序的元素大小,這裡是Int型別;
第四個是比較函式的指標,(int (*)(const void *,const void *))
num_comp
是要比較函式的地址;
#include<iostream>
#include<stdlib.h>
#include<ctime>
using namespace std;
int num_comp(const int *a,const int *b);
int main()
{
int num[100]={0};
srand(time(0));
//陣列初始化,填滿0-100隨機數;
for(int i=0;i<100;i++)
num[i]=rand()%101;
//升序排序;
qsort( num,100,sizeof(int),(int (*)(const void *,const void *))num_comp);
//輸出;
for(int i=0;i<100;i++)
cout<<num[i]<<' ';
}
int num_comp(const int *a,const int *b)
{
if(*a==*b)
return 0;
return *a>*b?1:-1;
}
如果想要進行降序排列,只需要修改return *a>*b?1:-1;
變成return *a<*b?1:-1;
即可.
二分查詢
C庫<stdlib.h>中提供了二分查詢函式,用於解決在已排序陣列中尋找一個數字;
其函式原型是:
void *bsearch( const void *key, const void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );
引數說明:
1、key是要尋找的關鍵數字,傳入時以地址方式傳入;
2、buf是要尋找的陣列,傳入首地址;
3、num是陣列的元素個數,可以用巨集定義解決;
4、size是陣列元素的大小;
5、比較函式;
呼叫方法:
需要使用者提供一個比較函式,同上面快排的比較函式;
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
#define SIZE(x) sizeof(x)/sizeof(x[0]) //巨集定義陣列元素個數;
typedef int(*COMP_P)(const void *,const void *); //定義指向比較函式的指標型別;
int num_comp(const int *a,const int *b);
int main()
{
//隨機初始化陣列;
int num[100]={0};
srand(time(0));
for(int i=0;i<100;i++)
num[i]=rand()%101;
//升序排列;
qsort(num,100,sizeof(int),(int (*)(const void *,const void *)) num_comp);
//檢視已排序陣列;
for(int i=0;i<100;i++)
cout<<num[i]<<' ';
//輸入要查詢的數字;
int number=5;
cin>>number;
//二分查詢;
int *p=(int *)bsearch(&number,num,SIZE(num),sizeof(int),(COMP_P)num_comp);
//列印查詢資料;
if(p!=NULL)
{
cout<<endl<<*p;
cout<<endl<<"index is:"<<p-num;
}
else
cout<<endl<<"not found"<<endl;
}
int num_comp(const int *a,const int *b)
{
if(*a==*b)
return 0;
return *a>*b?1:-1;
}
需要注意的是,這裡定義了一個指向比較函式的指標型別COMP_P
,在傳入函式地址時,將函式型別轉換一下。
而且bsearch函式返回的不是要查詢數字在陣列中的索引,而是返回查詢到的數字的指標,因此需要定義一個int *p
的指標來接收這個指標,如果沒有找到返回NULL