常用算法笔记

		
二叉树 
	树形的最简单的模型,每个节点最多有两个子节点
	一般来说,非二叉树,可以简化成二叉树
	每个子节点有且仅有一个父节点,整棵树只有一个根节点
	
	具有递归的结构特征,用递归的方法处理,可以简化算法
	
	三种遍历序:
		前序遍历 D-L-R
		中序遍历 L-D-R
		后序遍历 L-R-D
	比如:1是根节点  2是左子节点  3是右子节点
     前序遍历   1 2 3 
     中序遍历   2 1 3 
     后序遍历   2 3 1
	 
	二叉树的一般形式:
		根节点、枝节点、叶节点
		父节点和子节点
		左子节点和右子节点
		左子树和右子树
		大小和高度(深度)
	满二叉树和完全二叉树
	
	满二叉树:
		每层节点数均达到最大值
		所有枝节点均有左右子树
	完全二叉树:
		前面n-1 层是满的,最后1层可以不满,
		但是从左向右连续排列
	
	平衡二叉树:
		左右层数不能相差1的;
		
	二叉树的编码实现:
		顺序二叉树 -----数组只能还原完全二叉树,所以不是完全二叉树的 需要变成完全二叉树
		      最大的问题  就是如果二叉树离完全二叉树标准特别远,内存的浪费非常大。
			  因此二叉树虽然可以用 顺序结构实现,但更常见的用链表实现。
			  
		链式表二叉树
			每个节点由 数据、左子节点和右子节点组成(二叉链表)。也可以加上父节点指针(三叉链表)。
			二叉链表实现的二叉树 单向的; 三叉链表实现的是二叉树是 双向的。
			struct  BsTreeNode{
				int data;//数据
				struct BsTreeNode* left;//左子节点,也可以代表左边的子树
				struct BsTreeNode* right;//右子节点,也可以代表右边的子树
				
			};
			
			编码实现 有序二叉树:
			
			有序二叉树的原理:
				首先有一个根节点(第一个节点),放入第二个节点的时候,和根节点比较,如果比根节点大,放
			在根节点的右边,如果小则放在左边。(相等的话,看情况处理)。
				左右子树亦分别为有序二叉树。
			
			基于有序二叉树的排序和查找,可获得O(logN)级的平均时间复杂度




回顾:
	二叉树,最简单的树型结构,每个父节点最多有两个子节点
	二叉树具备递归的特征,所以编码时会大量使用递归。
	二叉树有顺序结构和链式结构两种实现方式,顺序结构的实现方式必须存储完全二叉树,
	不是完全二叉树的用空节点补成二叉树以后存储,因此内存上浪费比较大。
	链式结构的二叉树分为二叉链表实现和三叉链表实现,三叉链表多了父节点的指针。
	
	二叉树的遍历分为三种:前序、中序、后序
	
			
算法: 
	
	数据结构 存一起 
	算法  算一下
	
	广义上说,算法就是解决问题的方法。(说到底是数学问题)
	
	排序算法:----无序变成有序
		冒泡、选择、插入、快速、归并
	查找算法:----查找数据
		线性查找(从头到尾查找)二分查找(有序,从中间开始查找)
		
	
	冒泡排序:排序有升序和降序,升序就是从小到大,降序就是从大到小。
		算法: 
			相邻的比较,如果前面比后面大,交换。从第一对比到最后一对,最大就在最后面。
			依次对前面的元素进行相同的操作。n-1轮以后,排序成功。
			假如有一轮 依次都没有交换的话,则说明有序了。
			
			
			1. 相邻的预算两两比较,前者大于后者,彼此交换
			2. 从第一对到最后一对,最大元素沉降到最后
			3. 针对未排序部分,重复以上步骤,沉降次大值 
			4. 每次扫描越来越少的元素,直至不再发生交换
			
		评价:
		
			平均时间复杂度O(N的平方)
			稳定排序
			对数据的有序性非常敏感
		
		冒泡排序效率总体来说是比较低的。平均时间复杂度O的平方,就是N的平方次。
		但如果排序前就基本有序的话,则冒泡的效率就很高了。
		
  1 #include 
  2 #include 
  3 //数组做参数,必须指定数组长度,数组不能返回
  4 void bubble_sort(int data[],size_t size){//冒泡排序
  5     int i,j;
  6     for(i=0;i data[j+1]){//前面的比后面大
 12                 int temp = data[j];//交换算法
 13                 data[j] = data[j+1];
 14                 data[j+1] = temp;
 15                 flag=0;//发生了交换
 16             }
 17         }
 18         if (flag) break;//没有交换就退出
 19     }
 20 }
 21 int main()
 22 {
 23     int a[]={4,3,2,1,5,7,6};
 24     bubble_sort(a,7);
 25     int i;
 26     for(i=0;i<7;i++)
 27         printf("%d\n",a[i]);
 28     return 0;
 29 }

	插入排序  1-n
		算法: 
			第一个元素必然有序,然后把第二个到第n个元素插入前面的有序序列中,保证每次插入以后依然有序。
		
		如何保持插入后依然有序呢?
			把插入的数据和前面的数据进行比较,如果插入数据比前面数据小的话,前面的数据后移一位,插入数据
			继续向前比较,如果插入数据不比前面的数据小的话,把数据插入到前面的数据后面即可。如果已经比较
			到最前面的数据话,插入数据依然最小,插入数据放在第一位即可。
			
		
			1 首元素自然有序
			2 取出下一个元素,对已排序序列,从后向前扫描 
			3 大于被取出元素者后移
			4 小于等于被取出元素者,将被取出元素插入其后
			5 重复步骤2,直至处理完所有元素
		评价 
			平均时间复杂度O(N的平方)
			稳定排序
			对数据的有序性非常敏感
			不交换只移动,优于冒泡排序
 
		
  1 #include 
  2 #include 
  3 
  4 void insert_sort(int data[],size_t size){//插入排序
  5     int i,j;
  6     for(i=1;i0 && inserted < data[j-1]);j--){//从最后向前依次比较
  9             data[j] = data[j-1];//后移动一位,不需要交换
 10         }
 11         data[j] = inserted;//j就是inserted应该插入的下标
 12     
 13     }
 14 
 15 }
 16 
 17 int main()
 18 {   
 19     int a[]={4,3,2,1,5,7,6};
 20     insert_sort(a,7);
 21     int i;
 22     for(i=0;i<7;i++)
 23         printf("%d\n",a[i]);
 24     return 0;
 25 }

选择排序:

	求数组最小值的算法:
	int arr[];
	int min = arr[0];
	for(i=0;i
  2 #include 
  3 void select_sort(int data[],size_t size){//选择排序
  4     //思路:先从头开始记录最小值的下标,然后和i下标做数据交换
  5     int i,j,min;
  6     for (i=0;i
  2 #include 
  3 void quick_sort(int data[],size_t left,size_t right){//快速排序,全或部分
  4     size_t p = (left+right)/2;//以中间做基准
  5     int num = data[p];//把基准数取出来。
  6     int i = left;
  7     int j = right;
  8     while(i=p || numdata[j]);j--);
 16         if (j>p)
 17         {
 18             data[p] = data[j];
 19             p = j;
 20         }
 21     }
 22     data[p] = num;//基准数放入应该在的位置,归位
 23     if ((p - left) > 1)  quick_sort(data,left,p-1);
 24     if ((right - p) > 1)  quick_sort(data,p+1,right);
 25 }   
 26 int main()
 27 {
 28     int data[]={4,3,5,7,1,2,6};
 29     quick_sort(data,0,6);
 30     int i;
 31     for (i=0;i<7;i++)
 32         printf("%d\n",data[i]);
 33     return 0;
 34 }
	
	
	查找算法 :
		线性查找-----从头到尾找一遍,如果有,就退出循环,如果没有,循环结束就知道了。
		
		二分查找-----必须是有序元素才能使用二分查找。
		
		从中间点开始查找,如果大于 去后半部分,如果小于 去前半部分。
		
		每次查找都是从中间点开始。
		
		
  1 #include 
  2 #include 
  3 //返回find的下标,如果找不到返回-1;
  4 int line_find(int data[],size_t size,int find){
  5     int i;
  6     for (i=0;idata[mid]) left = mid + 1;
 21         else return mid;
 22     }
 23     return -1;
 24 }
 25 int main()
 26 {
 27     int data[]={7,2,4,5,1,3,6};
 28     int in = line_find(data,7,2);
 29     printf("in = %d\n",in);
 30     int in1 = line_find(data,7,20);
 31     printf("in1 = %d\n",in1);
 32     int data2[]={1,2,3,4,5,6,7,8};
 33     int in2 = half_find(data2,7,2);
 34     printf("in2 = %d\n",in2);
 35     int in3 = half_find(data2,7,20);
 36     printf("in3 = %d\n",in3);
 37 
 38 }
 39 

你可能感兴趣的:(C,&,C++,数据结构)