数据结构基础(1) --Swap & Bubble-Sort & Select-Sort

本文介绍了C++中实现swap函数的两种方法:通过指针和引用,并展示了如何使用std::swap实现冒泡排序和选择排序算法。文章还讨论了这些自定义排序算法的效率问题,并推荐使用STL中的std::sort。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Swap的简单实现

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //C语言方式(by-pointer):  
  2. template <typename Type>  
  3. bool swapByPointer(Type *pointer1, Type *pointer2)  
  4. {  
  5.     //确保两个指针不会指向同一个对象  
  6.     if (pointer1 == NULL || pointer2 == NULL)  
  7.     {  
  8.         return false;  
  9.     }  
  10.   
  11.     if (pointer1 != pointer2)  
  12.     {  
  13.         Type tmp = *pointer1;  
  14.         *pointer1 = *pointer2;  
  15.         *pointer2 = tmp;  
  16.     }  
  17.   
  18.     return true;  
  19. }  

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //C++特有方式(by-reference):  
  2. template <typename Type>  
  3. void swapByReference(Type &value1, Type &value2)  
  4. {  
  5.     if (value2 != value1)  
  6.     {  
  7.         Type tmp = value1;  
  8.         value1 = value2;  
  9.         value2 = tmp;  
  10.     }  
  11. }  

小结:

虽然我们自己实现了swap,但我们还是比较推荐使用C++ STL已经实现好的std::swap()函数,其存在于命名空间std中,使用实例如下面的<冒泡排序>.

  

冒泡排序(Bubble-Sort)

算法思想:

从左到右扫描数据,找出最大的元素,将其放到数组右边;

过程:

循环比较相邻的两个数,如果左边的数比右边的大,则交换两个数;

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //实现:注意代码中的三个注意点(x):  
  2. template <typename Type>  
  3. void bubbleSort(Type *begin, Type *end)  
  4. {  
  5.     if ((begin == end) || (begin == NULL) || (end == NULL))  
  6.         return ;  
  7.   
  8.     int length = end - begin;  
  9.     //注意点(1):保证一旦数组有序, 则会直接停止排序, 不会在继续进行无用的循环  
  10.     bool isOrder = false;  
  11.   
  12.     //外层循环控制扫描次数(length-1)  
  13.     //注意点(2):N个元素其实只需N-1次扫描  
  14.     for (int i = 0; !isOrder && i < length-1; ++i)  
  15.     {  
  16.         //首先假定这次数组已经有序  
  17.         isOrder = true;  
  18.         //注意点(3):确保能够从0扫描到最后一个未排序的元素  
  19.         for (Type *iter = begin; iter < end-i-1; ++iter)  
  20.         {  
  21.             //如果前面的左边的元素>右边的元素  
  22.             if (*iter > *(iter+1))  
  23.             {  
  24.                 //交换  
  25.                 std::swap(*iter, *(iter+1));  
  26.                 isOrder = false;  
  27.             }  
  28.         }  
  29.     }  
  30. }  
  31.   
  32. template <typename Type>  
  33. void bubbleSort(Type *array, int length)  
  34. {  
  35.     return bubbleSort(array, array+length);  
  36. }  

选择排序(Select-Sort)

思想:

从当前尚未排序的序列中选择一个最小的元素, 将之放到已排序的序列的队列的末尾;

要点:

1.注意三个指针(inner, outer, miner)所代表的含义;

2.同时注意是从未排序的序列中进行查找最小元素!

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //实现  
  2. template <typename Type>  
  3. void selectSort(Type *begin, Type *end)  
  4. {  
  5.     if ((begin == end) || (begin == NULL) || (end == NULL))  
  6.         return ;  
  7.   
  8.     //只要循环到最后一个元素的前一个就行了,因为剩下的那个肯定是最大的  
  9.     for (Type *outer = begin; outer < end-1; ++outer)  
  10.     {  
  11.         //注意:是从尚未排序的序列中查找(miner = outer, inner = outer+1)  
  12.         Type *miner = outer;  
  13.         //从miner+1开始遍历数组, 寻找一个元素值小于*miner的  
  14.         for (Type *inner = outer+1; inner < end; ++inner)  
  15.         {  
  16.             if (*inner < *miner)  
  17.                 miner = inner;  
  18.         }  
  19.   
  20.         if (miner != outer)  
  21.             std::swap(*miner, *outer);  
  22.     }  
  23. }  
  24.   
  25. //为了能够让STL的标准容器如vector使用  
  26. template <typename Iterator>  
  27. void selectSort(Iterator iter1, Iterator iter2)  
  28. {  
  29.     return selectSort(&(*iter1), &(*iter2));  
  30. }  
  31.   
  32. template <typename Type>  
  33. void selectSort(Type *array, int length)  
  34. {  
  35.     return selectSort(array, array+length);  
  36. }  

小结:

虽然我们自己实现了Bubble-Sort和Select-Sort,但我们在实际软件开发中一般是不会用到的,因为的它的效率为O(N^2),效率太慢^_^, 因此我们还是推荐使用C++ STL中已经实现了的std::sort(), 其内部原理使用了快速排序, 效率为O(logN)速度非常快.

 

附-测试程序

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int main()  
  2. {  
  3.     srand(time(NULL));  
  4.     vector<double> dVec;  
  5.     int count = 10;  
  6.     while (count --)  
  7.     {  
  8.         dVec.push_back((rand()%1000)/100.0);  
  9.     }  
  10.   
  11.     selectSort(dVec.begin(), dVec.end());  
  12.     for (vector<double>::iterator iter = dVec.begin(); iter < dVec.end(); ++iter)  
  13.     {  
  14.         cout << *iter << endl;  
  15.     }  
  16.   
  17.     return 0;  
  18. }  
在C语言中,为了实现一个通用的排序函数,你可以创建一个模板函数,使用泛型或C99中的`void *`指针进行操作。这里我将提供一个简单的示例,展示了如何使用`void *`指针来适应不同类型的数据,并实现三种排序算法(冒泡排序、插入排序和选择排序)的通用版本,用于对任意类型的元素进行逆序排列。 ```c #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; // 使用void *指针的通用比较函数 int compare(const void *a, const void *b) { // 假设我们有一个结构体,包含要比较的值和其他信息 struct MyData { double value; // 其他成员... } *dataA = (struct MyData *)a, *dataB = (struct MyData *)b; return dataB-&gt;value - dataA-&gt;value; // 按逆序排列 } // 冒泡排序通用版 void bubbleSort(void *arr, int n, int (*compare)(const void *, const void *)) { for (size_t i = 0; i &lt; n - 1; ++i) { for (size_t j = 0; j &lt; n - i - 1; ++j) { if ((*compare)((char*)arr + j * sizeof(struct MyData), (char*)arr + (j + 1) * sizeof(struct MyData)) &gt; 0) // 如果逆序,则交换 swap((struct MyData*)arr + j, (struct MyData*)arr + (j + 1)); } } } // 插入排序通用版 void insertionSort(void *arr, int n, int (*compare)(const void *, const void *)) { for (size_t i = 1; i &lt; n; ++i) { struct MyData *current = (struct MyData*)arr + i, *temp = current; while (i != 0 &amp;&amp; (*compare)(temp, (char*)arr + (i - 1) * sizeof(struct MyData)) &gt; 0) { memmove(temp, temp - sizeof(struct MyData), (i - temp) * sizeof(struct MyData)); --i; } temp = (struct MyData*)arr + i; } } // 选择排序通用版 void selectionSort(void *arr, int n, int (*compare)(const void *, const void *)) { for (size_t i = 0; i &lt; n - 1; ++i) { size_t min_idx = i; for (size_t j = i + 1; j &lt; n; ++j) { if ((*compare)((char*)arr + j * sizeof(struct MyData), (char*)arr + min_idx * sizeof(struct MyData)) &lt; 0) min_idx = j; } if (min_idx != i) swap((struct MyData*)arr + i, (struct MyData*)arr + min_idx); } } // 通用swap函数 static inline void swap(struct MyData *a, struct MyData *b) { struct MyData temp = *a; *a = *b; *b = temp; } int main() { // 创建一个浮点数组 struct MyData arr[] = {5.2, 1.3, 8.7, 2.9, 4.6}; int n = sizeof(arr) / sizeof(arr[0]); // 对浮点数组进行逆序排列 bubbleSort(arr, n, compare); insertionSort(arr, n, compare); selectionSort(arr, n, compare); printf(&quot;After Bubble Sort:\n&quot;); for (int i = 0; i &lt; n; ++i) printf(&quot;%.2lf &quot;, ((double*)arr)[i].value); printf(&quot;\nAfter Insertion Sort:\n&quot;); for (int i = 0; i &lt; n; ++i) printf(&quot;%.2lf &quot;, ((double*)arr)[i].value); printf(&quot;\nAfter Selection Sort:\n&quot;); for (int i = 0; i &lt; n; ++i) printf(&quot;%.2lf &quot;, ((double*)arr)[i].value); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值