冒泡排序原理
1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3、针对所有的元素重复以上的步骤,除了最后一个。
4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
普通的数组的冒泡排序
void fun()
{
int arr[] = { 5, 4, 3, 2, 1 };
int i = 0;
int j = 0;
int tmp = 0;
int len = sizeof(arr) / sizeof(arr[0]);
for (j = 0; j < len - 1; j++)
{
for (i = 0; i < len - 1 - j; i++)
{
if (arr[i] > arr[i + 1])
{
tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
}
for (i = 0; i < len; i++){
printf("%d ",arr[i]);
}
}
普通数组的冒泡排序也可以使用指针实现
void fun02()
{
int arr[] = { 5, 4, 3, 2, 1 };
int *start = &arr[0];
int *start_next = start + 1;
int *end = &arr[4];
int tmp = 0;
while (&arr[0] <= end)
{
start = &arr[0];
start_next = start + 1;
while (start_next < end-1)
{
if (*start > *start_next)
{
tmp = *start;
*start = *start_next;
*start_next = tmp;
}
start++;
start_next = start + 1;
}
end = start;
}
}
链表的冒泡排序
这样的话根据此方法便可以对链表进行排序了!
这个方法与使用指针对数组进行排序是一样的,只不过与之不停的地方在于数组要找到下一个元素的节点是非常容易的,对于链表可以使用next指针!
//单链表排序(冒泡排序)
void BubbleSort(pList * pplist)
{
pNode pCur = NULL;
pNode pnext = NULL;
pNode tail = NULL;
DataType tmp = 0;
assert(pplist != NULL);
assert(*pplist != NULL);
//外层循环
while (tail != (*pplist))
{
pCur = *pplist;
pnext = pCur->next;
while (pnext != tail)
{
if (pCur->data > pnext->data)
{
tmp = pCur->data;
pCur->data = pnext->data;
pnext->data = tmp;
}
pCur = pnext;
pnext = pnext->next;
}
//tail指针前移
tail = pCur;
}
}
优化
- 如果是空链表或者只有一个元素的链表则不进行排序
- 如果某一趟排完之后就有序,那么直接跳出循环不再排序
//单链表排序(冒泡排序)
void BubbleSort(pList * pplist)
{
pNode pCur = NULL;
pNode pnext = NULL;
pNode tail = NULL;
DataType tmp = 0;
//冒泡排序算法优化,定义标志位
int flag = 0;
assert(pplist != NULL);
//只有一个元素或者是空链表时候不进行排序
if (*pplist == NULL || (*pplist)->next == NULL)
return;
//外层循环
while (tail != (*pplist))
{
pCur = *pplist;
pnext = pCur->next;
while (pnext != tail)
{
if (pCur->data > pnext->data)
{
//交换了之后修改标志位
flag = 1;
tmp = pCur->data;
pCur->data = pnext->data;
pnext->data = tmp;
}
pCur = pnext;
pnext = pnext->next;
}
//tail指针前移
tail = pCur;
if (flag == 0) //未经改变的时候直接跳出循环
break;
}
}
算法稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。