目錄
- qsort函式原型
- compar引數
- int 陣列排序
- 結構體排序
- 字串指標陣列排序
- 字串二維陣列排序
- 整型二維陣列(力扣題目)
qsort函式原型
void qsort(
void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *)
);
??頭檔案:<stdlib.h>
??函式功能:qsort()函式的功能是對陣列進行排序,陣列有nmemb個元素,每個元素大小為size,
??引數base - base指向陣列的起始地址,通常該位置傳入的是一個陣列名
??引數nmemb - nmemb表示該陣列的元素個數
??引數size - size表示該陣列中每個元素的大小(位元組數)
??引數(*compar)(const void *, const void *) - 此為指向比較函式的函式指標,決定了排序的順序,
??函式回傳值:無
??注意:如果兩個元素的值是相同的,那么它們的前后順序是不確定的,也就是說qsort()是一個不穩定的排序演算法,
compar引數
??compar引數是qsort函式排序的核心內容,它指向一個比較兩個元素的函式,注意兩個形參必須是const void *型,同時在呼叫compar 函式(compar實質為函式指標,這里稱它所指向的函式也為compar)時,傳入的實參也必須轉換成const void *型,在compar函式內部會將const void *型轉換成實際型別,見下文,
int compar(const void *p1, const void *p2);
??如果compar回傳值小于0(< 0),那么p1所指向元素會被排在p2所指向元素的前面
??如果compar回傳值等于0(= 0),那么p1所指向元素與p2所指向元素的順序不確定
??如果compar回傳值大于0(> 0),那么p1所指向元素會被排在p2所指向元素的后面
??因此,如果想讓qsort()進行從小到大(升序)排序,那么一個通用的compar函式可以寫成這樣:
int compare (const void * a, const void * b)
{
if ( *(MyType*)a < *(MyType*)b ) return -1;
if ( *(MyType*)a == *(MyType*)b ) return 0;
if ( *(MyType*)a > *(MyType*)b ) return 1;
}
??注意:你要將MyType換成實際陣列元素的型別,
??或者
//升序排序
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
//降序排列
int compare (const void * a, const void * b)
{
return ( *(int*)b - *(int*)a );
}
int 陣列排序
/* qsort example */
#include <stdio.h>
#include <stdlib.h>
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main ()
{
int n;
qsort (values, sizeof(values)/sizeof(values[0]), sizeof(int), compare);
for (n=0; n<sizeof(values)/sizeof(values[0]); n++)
printf ("%d ",values[n]);
return 0;
}
結構體排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
// void qsort(void* base, size_t num, size_t size, int(*compare)(const void*, const void*))
typedef struct
{
char name[30]; // 學生姓名
int Chinese; // 語文成績
int Math; // 數學成績
int English; // 英語成績
}st;
int cmp(const void* a, const void* b)
{
st* pa = (st*)a;
st* pb = (st*)b;
int num1 = pa->Chinese + pa->English + pa->Math;
int num2 = pb->Chinese + pb->English + pb->Math;
//return (int)num1 - num2; // 從小到大,
return (int)num2 - num1; // 從大到小
}
int main(void)
{
st students[7] = {
{"周",97,68,45},
{"吳",100,32,88},
{"鄭",78,88,78},
{"王",87,90,89},
{"趙",87,77,66},
{"錢",59,68,98},
{"孫",62,73,89}
};
qsort(students, 7, sizeof(st), cmp); // 注意區別 students 與 st
for (int i = 0; i < 7; i++)
{
printf("%s%4d%4d%4d\t", students[i].name, students[i].Chinese, students[i].Math, students[i].English);
printf("總分:%d\n", students[i].Chinese + students[i].English + students[i].Math);
}
system("pause");
return 0;
}
字串指標陣列排序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int compare(const void *arg1, const void *arg2);
int
main(int argc, char** argv)
{
int i;
char *arr[5] = { "i", "love", "c", "programming", "language" };
qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(char *), compare);
for (i = 0; i < 5; i++) {
printf("%s ", arr[i]);
}
printf("\n");
}
int compare(const void *arg1, const void *arg2) {
char *a = *(char**)arg1;
char *b = *(char**)arg2;
int result = strcmp(a, b);
if (result > 0) {
return 1;
}
else if (result < 0) {
return -1;
}
else {
return 0;
}
}
??那么我們向qsort傳入arr之后,qsort將arr理解為指向陣列中第一個元素的指標,所以形參表中,arg1和arg2其實是指向“指向常量字串的指標”的指標,是char**,而我們需要傳給strcmp這個字串比較函式的,是“指向字串的指標”,是char*,所以我們將void*轉換為char**,然后解參考,得到char*,賦予a和b,接下來使用strcmp對a和b進行比較,(陣列名本身算一層指標,而里面的內容又是一層指標,陣列存放的是指向字串的地址)
字串二維陣列排序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int compare(const void *arg1, const void *arg2);
int
main(int argc, char** argv)
{
int i;
char arr[5][16] = { "i", "love", "c", "programming", "language" };
qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), compare);
printf("%s\n", arr[0]);
for (i = 0; i < 5; i++) {
printf("%s ", arr[i]);
}
printf("\n");
}
int compare(const void *arg1, const void *arg2) {
char *a = (char*)arg1;
char *b = (char*)arg2;
int result = strcmp(a, b);
if (result > 0) {
return 1;
}
else if (result < 0) {
return -1;
}
else {
return 0;
}
}
??這里對二維陣列進行排序,其實是對二維陣列的第二維中存放的字串進行排序,所以qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), compare);對qsort函式的呼叫中,第二個引數是待排元素的個數(5個),第三個引數是待排元素的大小(16),
??我們將arr傳入qsort函式,qsort函式將arr理解為指向陣列第一個元素的指標,arr的第一個元素是arr[0][0],所以引數arg1和arg2指的是指向"a[i][0]"的指標,我們知道,a[i][0]是字符,就是char,所以arg1和arg2指的是char *,我們將void*轉換為char*,賦予a和b,呼叫strcmp函式對a和b進行比較,
整型二維陣列(力扣題目)
- 最接近原點的 K 個點
??我們有一個由平面上的點組成的串列 points,需要從中找出 K 個距離原點 (0, 0) 最近的點,(這里,平面上兩點之間的距離是歐幾里德距離,)你可以按任何順序回傳答案,除了點坐標的順序之外,答案確保是唯一的,
示例 1:
輸入:points = [[1,3],[-2,2]], K = 1
輸出:[[-2,2]]
解釋: (1, 3) 和原點之間的距離為sqrt(10), (-2, 2) 和原點之間的距離為 sqrt(8), 由于 sqrt(8) < sqrt(10),(-2, 2) 離原點更近, 我們只需要距離原點最近的 K = 1 個點,所以答案就是 [[-2,2]],
示例 2:
輸入:points = [[3,3],[5,-1],[-2,4]], K = 2
輸出:[[3,3],[-2,4]] (答案 [[-2,4],[3,3]] 也會被接受,)
提示:
1 <= K <= points.length <= 10000
-10000 < points[i][0] < 10000
-10000 < points[i][1] < 10000
/* qsort排序二維陣列,cmp的每個元素都是一個獨立的 int 陣列,也就是指標 */
int cmp(const void* a, const void* b) {
// 轉換為對應一維陣列
int* arry1 = *(int**)a;
int* arry2 = *(int**)b;
// 獲取對應arry1 的兩個元素
int x1 = *arry1;
int y1 = *(arry1 + 1);
int x2 = *arry2;
int y2 = *(arry2+1);
return (x1*x1 + y1*y1) - (x2*x2 + y2*y2);
}
int** kClosest(int** points, int pointsSize, int* pointsColSize, int K, int* returnSize, int** returnColumnSizes){
if(points==NULL || pointsSize==0 || K==0) return NULL;
qsort(points, pointsSize, sizeof(int)*pointsColSize[0], cmp);
/* 這里注意 qsort 的傳參,使用不當會報錯
Line 11: Char 11: runtime error: load of misaligned address 0x602000000032 for type 'int *', which requires 8 byte alignment (solution.c) 0x602000000032: note: pointer points here
*/
// 指定return輸出的二維陣列是包含有幾個一維陣列
*returnSize = pointsSize > K ? K : pointsSize;
*returnColumnSizes = (int*)malloc(sizeof(int*)*(*returnSize));
// 指定每個一維陣列的 col
for(int i = 0; i< (*returnSize); i++) {
(*returnColumnSizes)[i] = 2;
}
return points;
}
有任何問題,均可通過公告中的二維碼聯系我
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/247016.html
標籤:嵌入式
