如何写一个可以排所有类型的冒泡排序

目录

        1.分析快速排序qsort

        2.分析思路

        3.代码实现


        1.分析快速排序qsort函数

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

                void *base 传首元素的地址

                size_t num 传数组的长度

                size_t size 传每个元素的字节大小

                int (*compar)(const void*,const void *)是一个函数的地址

                这个函数是自己写的判断函数,返回值是int

                如果第一个元素大于第二个元素返回大于一的数

                如果第一个元素等于第二个元素返回等于一的数

                如果第一个元素小于第二个元素返回小于一的数

         2.思路分析

                既然分析出qsort函数每个参数的意思那就可以通过分析参数的用处来实现通用的冒泡排序

        void *base 首元素的地址不用说,先将首元素的地址传过去定位这个数组

        size_t num 数组的长度,需要这个参数是为了数组确定到哪结束

        size_t size 每个元素的字节大小是为了确定找到下一个字符串要走多大的空间

        int(*compar)(const void*,const void*)是将相邻的两个元素传入这个数组用用户的方法来判断相邻的两个元素谁大谁小。

        知道以上信息,pop_sort就可以写起来了

        首先冒泡排序的通用模式肯定先要将冒泡排序写出来

#include <stdio.h>

void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
    int i=0;
    int j=0;
    for(i=0;i<num;i++)//确定趟数
    {
        for(j=0;j<num-i-1;j++)//确定每趟的次数
        {
            
        }
    }

}

        既然用户已经按照规则将判断元素那个大那个小的函数写出来了那就可以利用,用户函数的返回值来进行按一定规则进行排序(这里选择的是升序),由于用户没有将相邻两个元素传入他的方法,所以我们需要将相邻两个元素的地址传入这个方法

#include <stdio.h>

void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
    int i=0;
    int j=0;
    for(i=0;i<num;i++)//确定趟数
    {
        for(j=0;j<num-i-1;j++)//确定每趟的次数
        {
          if(cmp((char*)base+j*sz,(char*)base+(j+1)*sz)>0)
           {
            //base是首元素的地址,sz是元素的大小,用j和j+1正好相邻,用j,j+1分别乘元素大小得到
            //相邻两个数组的大小,传入用户写的函数中得到的返回值于0比较,由于是升序,所以返回是大
            //于0的是开始交换
           }   
        }
    }

}

        写一个交换函数,由于我们不知道传上来的数据类型是什么。所以采取一个字节一个字节的换

#include <stdio.h>

void swap(char *buf1,char*buf2,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        char tmp=*buf1;
        *buf1=*buf2;
        *buf2=tmp;
        buf1++;
        buf2++;
    //每次要交换一个字节总共要交换sz个字节
    }
}

void pop_sort(void *base,int num,int sz,int (*cmp)(const void e1,const void e2))
{
    int i=0;
    int j=0;
    for(i=0;i<num;i++)//确定趟数
    {
        for(j=0;j<num-i-1;j++)//确定每趟的次数
        {
          if(cmp((char*)base+j*sz,(char*)base+(j+1)*sz)>0)
           {
              swap(char*)base+j*sz,(char*)base+(j+1)*sz),sz);
           }   
        }
    }

}

        代码实现

#include <stdio.h>

void swap(char* buf1, char* buf2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
//写一个通用的冒泡排序
void pop_sort(void* base, int num, int sz, int (*cmp)(const void* e1, void* e2))
{
	/
	int i = 0;
	int j = 0;
	for (i = 0; i < num; i++)//循环的趟数
	{
		for (j = 0; j < num - i - 1; j++)//每趟循环的次数
		{
			if (cmp((char*)base +j* sz, (char*)base +(j+1) * sz) > 0)
			{
				swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
			}
		}
	}
}
int cmp_int(void *e1,void *e2)
{
	return *((int *)e1) - *((int*)e2);
}
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr[0]);
	int num = sizeof(arr) / sizeof(arr[0]);
	pop_sort(arr, num, sz, cmp_int);
	int i = 0;
	for (i = 0; i < num; i++)
	{
		printf("%d", arr[i]);
	}
}

注意:

        void* 可以接收所有的指针,只需要用的时候强制转换成所以要的类型即可

        void* 不可以加减也不可以访问

        站在程序员的角度来写这个函数的时候,我们什么都不知道,所以要考虑所有情况

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
3); pq.push(1); pq.push(2); while (!pq.empty()) { std::cout << pq.top() << " "; 好的,以下是用 JavaScript 实现冒泡排序的代码: ```javascript function bubbleSort(array) { const len = array pq.pop(); } ``` 26. 不要在迭代器失效的情况下修改容器 在使用 STL 容.length; for (let i = 0; i < len; i++) { for (let j = 0; j <器时,应该注意容器的迭代器是否会因为修改容器而失效。如果迭代器失效 len - 1 - i; j++) { if (array[j] > array[j + 1]) { [array[j],,则可能会导致未定义的行为。 27. 不要在使用 std::vector、std::string 或 std::deque array[j + 1]] = [array[j + 1], array[j]]; } } } return array; } ``时使用迭代器的比较运算符 在使用 std::vector、std::string 或 std::deque 时,应` 这里的 `bubbleSort` 函数接收一个数组作为参数,然后使用双重循环遍历数组,每该避免使用迭代器的比较运算符,因为这可能会导致未定义的行为。 28.次比较相邻的两个元素,如果前一个元素比后一个元素大,则交换它们的位置 在使用 std::unique_ptr 时,使用 std::move 将所有权转移 在使用 std::unique_ptr 时,应。经过一轮比较后,最大的元素会被移动到数组的最后面。然后再进行下一轮比较,不断重复这个过程,直到所有元素都被好序为止。 使用该使用 std::move 函数将所有权转移。这可以避免不必要的拷贝和析构开销。例如示例: ```javascript const arr = [3, 1, 4, 1, 5, 9, 2: ``` std::unique_ptr<int> p1(new int(1)); std::unique_ptr<int> p2(std::move(p1, 6, 5, 3, 5]; const sortedArr = bubbleSort(arr); console.log(sortedArr); // 输出 [)); ``` 29. 使用 std::function 来存储函数对象 STL 提供了 std::function 类型,可以方便1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9] ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值