Getting Started with Algorithms to Giving Up

1. Quick review of algorithms (Station B is a good idea, it is best to have a basic review)

It would be great to watch this video when learning data structures for the first time. Children who change majors learn too many things in one year, which is too time-consuming.

     1.算法的复杂度
     2. 经典算法时间空间复杂度稳定性

Insert image description here
The three issues of time, space and stability

   1.归并排序的额外空间复杂度可以变成0(1),但是非常难,不需要掌握,有兴趣可以搜“归并排序内部缓存法
   2. “原地归并排序”的帖子都是垃圾,会让归并排序的时间复杂度变成0 (N-2)
   3.快速排序可以做到稳定性问题,但是非常难,不需要掌握,可以搜"01stable sort"
   4.所有的改进都不重要,因为目前没有找到时间复杂度0(N1ogN),额外空间复杂度0(1),又稳定的排序
   5.有一道题目,是奇数放在数组左边,偶数放在数组右边,还要求原始的相对次序不变,碰到这个问题,可以01标准,理论级算法。

Balance between sorting optimization
and o (N2) and o (NlogN), comprehensive For sorting, use NlogN for large samples and N2
for small samples. The internal sorting algorithm is a comprehensive sorting algorithm and a complex sorting strategy

Hash table and ordered list
c++ map, set table unsortedmap: [key-> value]
Time complexity Constant level addition, deletion, modification and query

base type Pass by value, copy value
Custom type Passed by reference, 8-byte memory address

Usage of ordered list
1. Internally organize the structure according to Key, hash implementation, ordered list can be implemented, key can be compared , the smallest key value, the largest key value, red-black tree, AVL tree, sb tree, and jump list all belong to the ordered list structure, and the implementation cost is O (Nlogn) < a i=4> 2. Custom type, you need to provide a submitter to compare key values

Linked list structure
1. Reverse one-way and two-way linked lists (multiple pointers pre cur next)
Important tips
1. Additional data structures
2. Fast and slow pointers Don’t understand
Palindrome linked list: borrow stack, (all , half a part)
Fast and slow pointers: Consider the boundary conditions of the midpoint
Slow: one step at a time
Fast: two steps at a time
3 steps, odd and even lengths,
finite variables, original structure not changed, back and forth in disguise

 没有空间限制:接触额外数据结构
 **有空间限制:** 6个额外指针
   小于头尾接点指针
   等于头尾节点指针
   大于头尾节点指针
   !!!考虑边界情况

The shutter pointer searches for the loop head node

   设环外m,环内n节点,相遇时慢指针在环内走k步。此时慢走m+k步,快比慢多走m+k(快在绕圈圈等着慢),
   结论(m+k)%n=0。快回起点走m到环入口,此时慢在环内走了k+m步%n=0,即在环入口相遇

Tree structure
Recursive (first, middle, last) recursive order, There will be three return recursions at each level, this order is recursive order , the selection order is different, you can print in three orders: first, middle and last
^iod search (node){ // if (n == null){ return}

//
search( node.left);;
//
search (node.right) ;
}
Non-recursive
Pre-order traversal:
1. Push the stack, node Push into the stack, cur
2. Pop a node, process
3. (node ​​exists), press the right child first, then press the left child
4. Repeat until there is no node push
post-order traversal
and then add another auxiliary stack. In the case of pre-order traversal, the nodes will be popped out. Push another auxiliary stack

In-order traversal
1. Each tree is traversed from the head node to the left tree of the tree first
2. Then pop up the left tree and operate, if There are child nodes in the left tree, and the children will be pushed into
3. Repeat the operation
Breadth-first traversal
Queue< /span> Use the number of layers last A node mark, the number of nodes at the same level and level. Idea: use hashset to record the number of node layers
Return the maximum width: record the number of layers of each node

Applications of binary trees

  1. To determine whether it is a sorted tree, the left node is smaller than the root node and is smaller than the right
    Using inorder to traverse the left, middle and right should increase from small to large
    1 .Use the priority queue to enqueue it, use temporary variables to determine whether to increment, and use the stack to solve the problem
  2. Determine whether it is a full binary tree
    (1) Determine whether any node has a right child or a left child and it is directly No
    (2) Based on 1 When the first time encountered with incomplete left and right children, all subsequent nodes must be leaf nodes
    3. Determine whether it is a full binary tree
    (1) Binary tree depth, and then determine the relationship between the number of nodes and the depth
    (2) //The idea is not correct for breadth-first traversal. It is found that the node must have both the left and right children present, or it must be found that neither the left or right children are present (later in want)
// first define the return type, =>(leave,nodes_num)
class returnDate{
    
    
int leave,nodes_num;
bool tag;
returnDate(int leave,int nodes_num,bool tag){
    
    
this.leave = leave;
this.nodes_num = nodes_num;
this.tag =tag;
}
}
// 递归
returnDate isFull_tree(node x){
    
    
if(x==null) return (0,0,true);
returnDate nodeLeft = isFull_tree(x.left);
returnDate nodeRight = isFull_tree(x.right);
int nodes_nums, leave;
nodes_num= nodeLeft.nodes_num + nodeRight.nodes_num +1;
leave = nodeLeft.leave + 1if( nodeLeft.tag && nodeRight.tag && nodeLeft.leave==nodeRight.leave&&
     nodeLeft.nodes_num = nodeRight.nodes_nums){
    
    
     return nodes_num == 1>>leave -1 ? new returnDate(leave,nodes_num,ture) : new returndate(leave,nodes_num,false);
     }
return new returnDate(leave,nodes_num,false) ;
}
 4.判断是否为平衡二叉树
    **基于左子树和右子树寻求信息,并且左右为平衡树并且左右子树只差不大于1**
    递归学习构造 ,递归构造要一样!**如果对左右两树操作不一样,将左右树全局操作。**
class returnType{
    
    
int leave;
bool balanceT;
public:
     returnType(int num, bool b){
    
    
     this.leave = num;
     this.balanceT = b;
     }
}
returnType judeg_balacneT(node x){
    
    
if (x ==NUll) {
    
    
 returnType a = new returnType(0,ture);
 return a;
 }
 returnType nodeLeft = judge_balance(x.left);
 returnType nodeRight = judge_balance(x.right);
 int leave = max(nodeLeft.leave ,nodeRihgt.leave)+1;
 bool isBalanced = nodeLeft.balanceT && nodeRight.balanceT && abs(nodeLeft.leave -nodeRight.leave)<2
 returnType a  = new returnType(leave,isblanced);
 return a;
 }

Tree DP**** is based on the left and right tree information, and the entire set is recursive.

  1. Given two tree nodes o1 and o2, find the first ancestor node
    (1). List all the ancestor nodes of 01 in a queue, and then list the o2 node , determine whether it is in o1
   map<node,node> fatherMap;
   father.insert(head,head)
   hashmap(map fahterMap,node head){
    
    
	   if(head ==NULL) return;
	   
	   fatherMap.insert(head.left,head);
	   fatherMap.insert(head.right,head);
	   hashMap(fatherMap, head.left);
	   hashMap(fatherMap,head>right);
   }
	
   Node LcommonAccent(Node head, Node o1, Node o2){
    
    
	   hashmap(fatherMap,head);
	   set<node> father_O1
	   node cur = o1;
	   while(cur!=fatherMap[cur]){
    
    
		   father_O1.insert(fatherMap[cur];
		   cur = fatherMap[cur];
	   }
	   father_O1.insert(head);
	 cur = o2;
	 while(cur!=fatherMap(cur){
    
    
		 if (father_O1.count(cur) >0) return cur;
		 
		 cur = fatherMap(cur);
	 }
		   return head;
	   
   }

(2). Use recursion to solve the problem. The head node asks the left and right trees respectively for traces of o1 and o2 nodes

node LCommonAccent(node head, node o1, node o2){
    
    
if (head ==null || head ==o1 || head ==o2 ||) return head;
node left = LCommonAccent(head.leaf, o1,o2);
node right = LCommonAccent(head.right,o1,o2);
if( left !=NULL && right !=NULL) return head;
return left == NULL ? right : left;
}
  1. The shortest path to find the successor node (in-order traversal, asbd, b's successor is d)
    Structural analysis:
    (1) x node has a right Tree, the leftmost node on the right tree
    (2) There is no right tree for the lower node, trace up to see if it is the left child of the father, (find the rightmost node of a certain subtree)
    (3) If it is the rightmost node of the entire tree, there is no successor node
node Most_Left(node x){
    
    
while(x.left != NULL)
    x = x.left;
return x;
}
node find_middleNext(node x)
{
    
    
  if(x.right != NULL)   return Most_Left(x);
  
  node parent = x.parent;// r如果没有自己hashmap
  while( parent != NULL && parent.left!= x){
    
    
   x = parent;
   parent = x.parent;
  }
  return parent;
}
  1. Serialization and deserialization of binary trees // Unique and temporary storage of binary tree structures
#include <iostream>
#include <map>
#include <set>
#include <queue>

using namespace std;

  struct node{
    
    
	   char value;
	   struct node * left=NULL;
	   struct node *right=NULL;

   };
  class Tree{
    
    
//	  private:

	   public:
	   node *head =NULL;
       node *head_form=NULL;
//	   Tree(){};
	   Tree(char a){
    
    
		   node * n = new node;
           *n = {
    
    a,NULL,NULL};
            this->head  = n  ;
	   }
       void init(node* head,char* s,int i){
    
    

	    queue<node*> nodes;
		nodes.push(head);
		while(!nodes.empty()){
    
    
			node* head_tem = nodes.front();
			    nodes.pop();
				node *a = new node;
		     	node *b = new node;
			if(	s[i] != '\0'){
    
    
				*a={
    
    s[i++],NULL,NULL};
                head_tem->left = a;
                nodes.push(head_tem->left);
			}else
            {
    
    
                *a={
    
    '#',NULL,NULL};
                head_tem->left = a;
            }

			if(	s[i] != '\0'){
    
    
				*b={
    
    s[i++],NULL,NULL};
                head_tem->right = b;
                nodes.push(head_tem->right);
			}else
            {
    
    
                *b={
    
    '#',NULL,NULL};
                head_tem->right = b;
            }


		   }
	  } //put a RFL-tree-queue-to initiate the tree
       void form_tree(char *s,int i){
    
    
           if(s == NULL || s[i] =='\0' ) this->head_form =NULL;
           else {
    
    
               node *n = new node;
               this->head_form = n;
               RFL_queue_init(this->head_form,s,i);
           }
       }
       void RFL_queue_init(node*& head_form, char* s,int &i){
    
    
           if (s== NULL || s[i]== '\0') return;
           if(s[i] == '#' ) {
    
    
               i++;
               return;
           }

           node *n = new node;
           *n = {
    
    s[i++],NULL,NULL};
           head_form = n;
           RFL_queue_init(head_form->left, s,i);
           RFL_queue_init(head_form->right,s,i);
       }
       void print(node *head){
    
    
		  if(head == NULL)  return;

		  cout<< head->value;
		  print(head->left);
		  print(head->right);
	  }


   };

  int i= 0;
int main()
{
    
    
    char s[] = "12345678";
   Tree *a = new  Tree('a');
   int i = 0;
   a->init(a->head,s,0);
   a->print(a->head);
   cout<<endl;
   char tem[] ="a137##8##4##25##6##";
   cout<<"the new tree";
   a->form_tree(tem,i);
   a->print(a->head_form);
  // cout << (a->head)->value;
   delete a;
   return 0;

}
  1. The problem of convex and concave marks in origami creases, one fold is convex, the other two are convex and concave, the three are convex and concave (drawn as a binary tree)
       void ATprint(node *head,int i,bool flag){
    
    
           if(i >2) return;
           head = new node;
           ATprint(head->left,i+1,true);
           if(flag)
               cout<<"Tu ";
           else
               cout<<"Ao ";
           ATprint(head->right,i+1,false);
       }

Guess you like

Origin blog.csdn.net/huangdxian/article/details/121244573