冒泡排序算法

本文详细介绍了冒泡排序的基本原理和优化方法,包括其在数组和链表上的应用。提供了C语言实现的冒泡排序代码示例,包括针对链表的两种版本的冒泡排序算法,一种交换节点,另一种仅交换节点中的值。讨论了算法的时间复杂度和空间复杂度,并展示了如何减少比较次数。
摘要由CSDN通过智能技术生成

    冒泡排序:
        每次排序都将待排序列中最大的元素移至数组末尾。
        空间复杂度O(1)
        时间复杂度O(n^2)
        冒泡算法具有稳定性。
    冒泡排序算法即适用于数组又适用于链表。

代码展示:

#include<stdio.h>
#include<stdlib.h>
#define null NULL 
/*
	冒泡排序:
		每次排序都将待排序列中最大的元素移至数组末尾。
		空间复杂度O(1)
		时间复杂度O(n^2)
		冒泡算法具有稳定性。
	冒泡排序算法即适用于数组又适用于链表。
	 
*/



//由于每次执行交换 只能消除一个逆序数.
//而一个随机数组的逆序数是O(n^2)个,所以冒泡需要执行O(n^2)次交换才能消除全部逆序数,进而使得数组有序。 
//故 冒泡排序的时间复杂度为O(n^2). 
void BubbleSort(int a[] ,int n){
	
	int i ,j,temp;
	//n个元素,需要执行n-1轮冒泡 
	for(i = 1;i < n; i++){
		bool flag  = false;  //表示本趟冒泡是否发生交换的标志 
		//每轮冒泡需要进行比较的元素个数 
		for(j=0;j < n-i+1;j++){ 
			//前者比后者大,交换两元素的值, 每次交换只能消除一个逆序数 
			if(a[j] > a[j+1]){
				temp = a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
				flag = true; 
			}	
		} 
		//本趟遍历没有发生交换、说明表已有序 
			if(flag == false){
				return;
			}
	} 
} 

typedef struct LinkNode{
	int data;
	struct LinkNode *next; 
}LinkNode;
 
//创建一个链表 
void createLinkList(LinkNode *head, int a[],int n){
	//printf("%d\n",head);
	for(int i = 0;i < n; i++){
		LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
		s->data = a[i];
		s->next = null;
		head->next = s;
		head=head->next;				
	}
}

//针对链表的一个冒泡排序算法 (带头结点) 
//两种版本  第一种版本是交换结点    第二种版本是仅交换结点中元素的值 
//此版本是交换结点的版本 n为链表的长度 
void BubbleSortLinkList(LinkNode *head,int n){
	LinkNode *end = null; //end指针永远指向当前趟要比较到的最后一个元素。 
	//冒泡的轮数 n - 1 轮 
	for(int i = 1;i<n;i++){
		bool flag = false;
		LinkNode *s = head;
		//执行了一趟排序 
		while(s->next->next != end){
		//如果前面的元素大于后面的元素,交换两个结点 
			if(s->next->data > s->next->next->data){
				LinkNode *p  = s->next;
				LinkNode *q  = s->next->next;
				s->next = q;
				p->next = q->next;
				q->next = p;
				flag = true;	  
			}
			s = s->next;
		}
		//每趟走完之后,最大元素冒到数组末尾,下一趟比较的时候就要比上一趟少比较一次。  // 通过end指针在冒泡排序时可以减少比较次数。 
		end = s->next;
		if(flag == false){
			return;
		}
	}
}



//针对链表的一个冒泡排序算法 (带头结点) 
//两种版本  第一种版本是交换结点    第二种版本是仅交换结点中元素的值 
//此版本是仅交换结点中元素的值 n为链表的长度 
void BubbleSortLinkList2(LinkNode *head,int n){
	LinkNode *end = null; //end指针永远指向当前趟要比较到的最后一个元素。 
	//冒泡的轮数 n - 1 轮 
	for(int i = 1;i<n;i++){
		bool flag = false;
		LinkNode *s = head->next;
		//执行了一趟排序 
		while(s->next != end){
		//如果前面的元素大于后面的元素,交换两个结点 
			if(s->data > s->next->data){
				//交换值
				int temp = s->data;
				s->data = s->next->data;
				s->next->data = temp; 
				flag = true; 
			}
			s = s->next;
		}
		//每趟走完之后,最大元素冒到数组末尾,下一趟比较的时候就要比上一趟少比较一次。  // 通过end指针在冒泡排序时可以减少比较次数。 
		end = s;
		if(flag == false){
			return;
		}
	}
}

//输出链表的长度 
int printLinkListLength(LinkNode *head){
	int count=0;
	while(head->next != null){
		count++;
		head = head->next;
	}
	return count;
} 

//打印链表 
void printLinkList(LinkNode *head){
	while(head->next != null){
		printf("%d ",head->next->data);
		//别忘了让head指针后移 
		head = head->next;
	}
}


int main(int argc, char *argv[])
{
	int a[] = {5,1,4,2,7,18,23,3};
	//BubbleSort(a,8); 
	//for(int i  = 0 ;i<8;i++){
	//	printf("%d ",a[i]);
	//}
	LinkNode *head = (LinkNode *)malloc(sizeof(LinkNode));
	createLinkList(head,a,8);
	printLinkList(head);
	printf("\n");
	int length = printLinkListLength(head);
	BubbleSortLinkList2(head,length);
	printLinkList(head);
	return 0;
}

结果测试:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值