介绍:交换节点法的冒泡排序及优化
1.数组实现
#include <cstdio>
typedef long long ll;
using namespace std;
void out(ll a[], ll n)
{
for(int i = 0; i < n; i++)
printf("%lld ", a[i]);
printf("\n");
}
void bubble_sort(ll *a, ll n)
{
int pos = n-1;//每一趟的范围
while(pos)
{
int last = 0;//重置交换的最后位置
for(int i = 0; i < pos; i++)//优化的地方,从每次-1提高到最后交换的位置
{
if(a[i] > a[i+1])
{
int t = a[i];
a[i] = a[i+1];
a[i+1] = t;
last = i;
}
}
pos = last;//记录最后一次交换的位置,后面的由传递性可知是有序的
printf("%d\n", last);
}
out(a, n);
}
void bad_bubble_sort(ll *a, ll n)
{
for(int i = 0; i < n; i++)
{
bool flag = false;
for(int j = i; j < n-1; j++)
{
if(a[j] > a[j+1])
{
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
flag = true;
}
}
if(!flag) break;
}
out(a, n);
}
int main()
{
ll n, a[100];
while(~scanf("%lld", &n))
{
for(int i = 0; i < n; i++)
scanf("%lld", &a[i]);
bubble_sort(a, n);
bad_bubble_sort(a, n);
}
}
/*
10
3 2 1 4 4 4 4 4 4 4 4
*/
2.链表实现
#include <cstdio>
#include <cstdlib>
#include <conio.h>
using namespace std;
typedef struct _Node
{
int num;
_Node *next;
}Node;
Node *CreateLink()
{
Node *head, *tail;
head = (Node*)malloc(sizeof(Node));
tail = NULL;
head->next = NULL;
printf("输入数据的组数\n");
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
Node *p = (Node*)malloc(sizeof(Node));
scanf("%d", &p->num);
p->next = NULL;
if(tail == NULL)
head->next = p;
else
tail->next = p;
tail = p;
}
return head;
}
void print(Node *head)
{
Node *p;
for(p = head->next; p; p = p->next)
printf("%d\n", p->num);
}
/*
void Bubble_sort1(Node *head)//无优化的Bubble_sort
{
int cnt = 0;
Node *pre, *p, *tail;
tail = NULL;
while(head->next != tail)//当头结点的指针域不等于最后交换的元素时
{
cnt++;
pre = head;//前驱指针指向头节点(2个交换元素的前一个元素)
p = head->next;//目标指针指向首元元素,即第一个放数据的元素
while(p->next != tail)
{
if(p->num > p->next->num)//比较目标元素和它的下一个元素
{
//交换步骤画图有助理解
pre->next = p->next;//1连3
p->next = pre->next->next;//2连4
pre->next->next = p;//2连3
}
else
p = p->next;//如果交换了就不用执行这一步,因为p就被交换到下一位了(画图)
pre = pre->next;//前驱指针后移, 别漏了
}
tail = p;//每次向左缩进一位
}
printf("Bubble_sort1执行了%d趟\n", cnt);
}
*/
void Bubble_sort(Node *head)//优化的Bubble_sort
{
int cnt = 0;
Node *pre, *p, *pos;//pos表示每一趟的范围
pos = NULL;
while(head->next != pos)//当头结点的指针域不等于最后交换的元素时
{
cnt++;
pre = head;//前驱指针指向头节点(2个交换元素的前一个元素)
p = head->next;//目标指针指向首元元素,即第一个放数据的元素
Node *last = head->next;//重置交换的最后位置为首元元素
while(p->next != pos)
{
if(p->num > p->next->num)//比较目标元素和它的下一个元素
{
//交换步骤画图有助理解
pre->next = p->next;//1连3
p->next = pre->next->next;//2连4
pre->next->next = p;//2连3
last = p;
}
else
p = p->next;//如果交换了就不用执行这一步,因为p就被交换到下一位了(画图)
pre = pre->next;//前驱指针后移, 别漏了
}
pos = last;//每次向左缩进一位
}
printf("Bubble_sort执行了%d趟\n", cnt);
}
void Clear(Node *head)
{
Node *p,*q;
for(p = head; p; p = q)
{
q = p->next;
free(p);
}
}
int main()
{
while(1)
{
Node *head;
head = CreateLink();
printf("排序前\n");
print(head);
//Bubble_sort1(head);
Bubble_sort(head);
printf("排序后\n");
print(head);
Clear(head);
printf("按任意键刷新屏幕\n");
getch();
system("cls");
}
return 0;
}