算法

1.常用的排序算法及其时间、空间复杂度

			插入排序:对于一个数组来说,初始其有序数组元素个数为1,然后从第二个元素开始插入到有序数组中。对于每一次插入操作,从后往前遍历,若是当前元素大于要插入的元素,则继续前移一位,若是当前元素小于或等于要插入的元素,则将要插入的元素插入当前元素的后一位中。
			希尔排序:先取一个小于n的整数a作为第一个增量,然后将所有距离为a的倍数的记录放在同一个组中。现在各组内进行直接插入排序;然后取第二个增量b<a重复上述分组和排序,知道所取的增量为1,即所有记录放在同一组中进行直接插入排序为止。
			归并排序:采用分治法,对包含m个元素的待排序序列,将其看成m个长度为1的子序列,然后两两合并,得到n/2个长度为2或者1的有序子序列,然后继续两两归并,直到得到一个长度为m的有序序列。
			冒泡排序:对于包含n个元素的数组,重复遍历数组,首先比较第一个与第二个元素,若为逆序则交换元素位置,然后比较第二个和第三个元素,重复上诉操作。
			快速排序:首先设定一个分解值,通过该分解值将数组分成左右两部分。将大于或等于分解值的数据集中到数组右边,小于分界值的集中到数组左边。此时,左边部分中各元素均小于右边部分;然后又分别对左边和右边数据进行排序,分别选择一个分界值,将小于分界值的数放在左边,大于或等于的值放在右边。重复直至整个数组的排序完成。
			选择排序:从待排序的数据元素中选取最小的一个元素,存放在序列的起始位置,然后从剩余元素中找最小值,以此类推。
			堆排序:在堆的数据结构中,堆中的最大值总是位于根节点。将待排序的数据构造一个最大堆,然后将堆顶元素与待排序数组的最后一个元素交换位置,此时末尾元素就是最大值,然后将剩余元素重新构造成最大堆。

												算法    时间复杂度       空间复杂度      稳定性
												插入      n^2               1          稳定
												希尔     nlogn              1         不稳定
												归并     nlogn              n          稳定
												冒泡      n^2               1          稳定
												快速     nlogn            nlogn       不稳定
												选择      n^2               1         不稳定
												堆       nlogn              1         不稳定

2.手写快排代码

#include<iostream>
#include<vector>
using namespace std;
//首先找到一个参考值,将大于或等于参考值的数放在参考值后面;将小于参考值的数放在参考值前面
int on_quick_sort(vector<int> &nums,int left, int right){
//先从右向左移动,找到第一个小于k的值,将之保存在前面的空位中,此时该位置为空位;然后从左向右找到第一个大于等于k的值,将之保存在之前的空位中,此时该位置为空,直到左右指针相遇,此时相遇位置为空,则将参考值保存在空位置中,此时参考值左边均为小于参考值,右边均大于等于参考值
	int k=nums[left];//将当前数组范围内的第一个数作为参考值取出来保存,此时该位置位空位
	while(left<right){//因此需要判断左右指针还未相遇时,对值进行互换
		while(left<right&&k<=nums[right]){//从右往左,直到找到第一个小于参考值的值
			right--;
		}
		if(left<right){//将该值放入之前的空位置中,此时该位置为空位置
			nums[left++]=nums[right];
		}
		while(left<right&&nums[left]<k){//然后从左往右,找到第一个大于等于参考值的值
			left++;
		}
		if(left<right){//将该值放入之前的空位置中,此时该位置为空位置
			nums[right--]=nums[left];
		}
	}
	nums[left]=k;//左右指针相遇时,调整完成,将参考值放入最后的空位置中
	return left;//返回此时参考值的位置
}

int quick_sort(vector<int> &nums,int left,int right){
	if(left>=right){
		return 1;
	}
	int middle=on_quick_sort(nums,left,right);
	on_quick_sort(nums,left,middle-1);
	on_quick_sort(nums,middle+1,right);;
}
int main(){
	vector<int> p;
	int a;
	while(cin>>a){
		p.push_back(a);
	}
   int n=p.size();
   quick_sort(p,0,n-1);
   for(int i=0;i<n;i++){
		cout<<p[i]<' ';
	}
	return 0;
}

3.二叉树
3.1二叉树的逻辑结构: 每个节点最多两颗子树,子树有次序之分

//完全二叉树:除了第h层外,其他各层的结点数均达到最大个数。 若完全二叉树高度为h,则该二叉树有2^h-1个结点。
//满二叉树:除了最后一层无任何子结点以外,每一层上的所有结点都有两个子结点的二叉树

 typedef struct BTNode{
				int data;
				BTNode* lChild;
				BTNode* rChild;
			}BTNode;

3.2二叉树的层次遍历
在这里插入图片描述
则层次遍历的结果为ABCDEF。利用队列先进先出的特性来表示。先将A入队,然后A出队,访问A,将A 的子结点BC读入队列,,然后B出队,访问B的子结点,C出队访问C的子结点。

void level(BTNode *bt)
{
	if(bt!=NULL){
		int front,rear;
		BTNode *que[maxSize];
		front=rear=0;
		BTNode *p;
		rear=(rear+1)%maxSize;
		que[rear]=bt;
		while(front!=rear)
		{
			front=(front+1)%maxSize;
			p=que[front];
			Visit(p);
			if(p->lChild!=NULL)
			{
				rear=(rear+1)%maxSize;
				que[rear]=p->lChild;
			}
			if(p->rChild!=NULL)
			{
				rear=(rear+1)%maxSize;
				que[rear]=p->rChild;
			}
		}
	}
}

***3.3***二叉树的前序遍历
a.递归

void preorder(BTNode *root){
	if(root){
		visit(root);
		preorder(root->lChild);
		preorder(root-rChild);
	}
}

b.非递归

void preorder(BTNode *root){	
	if(root){
		BTNode *s[maxSize];
		int top=-1;
		BTNode *p=NULL;
		s[++top]=bt;
		while(top!=-1){
			p=s[top--];
			visit(p);
			if(p->rChild) s[++top]=p->rChild;
			if(p->lChild) s[++top]=p->lChild;
		}		
	}
}

3.4二叉树的中序遍历
a.递归

void inorder(BTNode *root){
	if(root){
		
		inorder(root->lChild);
		visit(root);
		inorder(root-rChild);
	}
}

b.非递归

void inorder(BTNode *root){
	if(root!=NULL){
		BTNode *s[maxSize];int top=-1;
		BTNode *p=NULL;
		p=bt;
		while(top!=-1||p!=NULL){
			while(p!=NULL){
				s[++top]=p;
				p=p->lChild;
			}
			if(top!=-1){
				p=s[top--];
				visit(p);
				p=p->rChild;
			}
		}
	}
}

***3.5***二叉树的后序遍历
a.递归

void postorder(BTNode *root){
	if(root){
		
		postorder(root->lChild);
		postorder(root-rChild);
		visit(root);
	}
}

b.非递归

void postorder(BTNode *root){	
	if(root){
		BTNode *s1[maxSize],*s2[maxSize];
		int top1=-1,top2=-1;
		BTNode *p=NULL;
		s1[++top]=bt;
		while(top1!=-1){
			p=s1[top--];
			s2[++top2]=p;
			if(p->lChild) s1[++top]=p->lChild;
			if(p->rChild) s1[++top]=p->rChild;
		}
		while(top2!=-1){
			p=s2[top2--];
			visit(p);
		}		
	}
}

4.树的高度和深度
高度是从下往上数,而深度是从上往下数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值