Verwenden Sie den Blasensortierungsalgorithmus, um die Funktion der qsort-Funktion zu realisieren


Was ist die qsort-Funktion?

Normalerweise können wir beim Schreiben von Sortieralgorithmen nur feste Typen sortieren, und qsort ist eine Funktion, die Daten jeden Typs sortieren kann. Funktionsprototyp:

void qsort (void* base, size_t num, size_t size, int ( compar)(const void ,const void*);

Basis: zeigt auf das erste Element der Daten, die Sie sortieren müssen;
Zahl: die Anzahl der Elemente, die Sie sortieren müssen;
Größe: die Größe eines einzelnen Elements in den zu sortierenden Daten in Bytes;
int ( compar)(const void ,const void* ): Dies ist ein Funktionszeiger und sein Rückgabewert ist int. Wenn die Daten, auf die der erste Parameter zeigt, größer sind als die Daten, auf die der zweite Parameter zeigt, wird eine Zahl größer als 0 zurückgegeben; wenn wenn es gleich ist, wird 0 zurückgegeben; andernfalls wird eine Zahl kleiner als 0 zurückgegeben

最后一个参数其实是然用户自己实现一个比较函数对两个数据
进行比较然后按要求进行返回。

Warum ist die Art der Basis void*?

Der Grund, warum der Basistyp void* ist, liegt darin, dass Zeiger vom Typ void Zeiger jedes beliebigen Typs empfangen können, z. B. Strukturzeiger, Array-Zeiger, Zeichenzeiger ... die alle von Zeigern vom Typ void empfangen werden können.
Fügen Sie hier eine Bildbeschreibung ein

Die vom Benutzer zu schreibende Vergleichsfunktion ist eigentlich überhaupt nicht schwierig, da sie sehr einfach ist, egal ob es sich um eine Zahl, ein Zeichen oder eine Zeichenfolge handelt:

//如果是浮点型酒吧int换成float或double,字符也一样
int Compare(const void* p1, const void* p2)
{
    
    
	return *((int*)p1) - *((int*)p2);
}
//字符串,因为strcmp函数的返回值刚好满足此要求所以可以直接调用
#include <string.h>
int Compare(const void* p1, const void* p2)
{
    
    
	return strcmp((char*)p1 ,(char*)p2);
}

Ideenanalyse

Da die Vergleichsfunktion vom Benutzer übergeben wird, müssen wir keinen Vergleich durchführen, wenn wir die Idee der Blasensortierung verwenden, um qsort zu implementieren. Wir können die vom Benutzer übergebene Vergleichsfunktion direkt aufrufen:

void My_qsort(void* base, int num, int size, int (*p)(const void*, const void*))
{
    
    
	for (int i = 0; i < num - 1; i++)
	{
    
    
		for (int j = 0; j < num - 1; j++)
		{
    
    
		//需要特别注意虽然void*类型的指针可以接收所有类型的指针但是却无法对其进行访问所以这里必须进行强制类型转换
			if (p((char*)base + size * j, (char*)base + size * (j + 1)) > 0)
			{
    
    
				//对数据进行交换
				Swape((char*)base + size * j, (char*)base + size * (j + 1), size);
			}
		}
	}
}

Um den Code prägnanter zu gestalten, habe ich den Datenaustausch als separate Funktion geschrieben:

void Swape(char* q1, char* q2, int size)
{
    
    
	for (int i = 0; i < size; i++)
	{
    
    
		char tmp = *q1;
		*q1 = *q2;
		*q2 = tmp;
		q1++;
		q2++;
	}
}

Vollständiger Code:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>

int Compare(const void* p1, const void* p2)
{
    
    
	return *((int*)p1) - *((int*)p2);
}

void Swape(char* q1, char* q2, int size)
{
    
    
	for (int i = 0; i < size; i++)
	{
    
    
		char tmp = *q1;
		*q1 = *q2;
		*q2 = tmp;
		q1++;
		q2++;
	}
}

void My_qsort(void* base, int num, int size, int (*p)(const void*, const void*))
{
    
    
	for (int i = 0; i < num - 1; i++)
	{
    
    
		for (int j = 0; j < num - 1; j++)
		{
    
    
			if (p((char*)base + size * j, (char*)base + size * (j + 1)) > 0)
			{
    
    
				//交换
				Swape((char*)base + size * j, (char*)base + size * (j + 1), size);
			}
		}
	}
}

int main()
{
    
    
	int arr[] = {
    
    2.6,4.3,9,23,8,0,9,2};
	int num = sizeof(arr) / sizeof(arr[0]);

	My_qsort(arr, num, sizeof(arr[0]), Compare);
	
	for (int i = 0; i < num; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/2302_76339343/article/details/131602336
Recomendado
Clasificación