Data structure and algorithm

Time:2019-10-22

Max subseqsum

  • Time complexity: t (n) = O (N3)
int MaxSubSeqSum(int arrays[],int length){
    int i,j,k,thisSum=0,maxSum=0;
    for(i=0;i<length;i++){
        for(j=i;j<length;j++){
            thisSum=0;
            for(k=i;k<=j;k++){
                thisSum+=arrays[k];
            }
            if(thisSum>maxSum)maxSum=thisSum;
        };
    }
    return maxSum;
}
Max subseqsum
  • Time complexity: t (n) = O (N2)
int MaxSubSeqSum(int arrays[],int length){
    int i,j,thisSum=0,maxSum=0;
    For (I = 0; I < length; I + +) {// I is the left end of the child column
        Thissum = 0; // sum of subsequences from arrays [i] to arrays [J]
        For (J = I; J < length; j + +) {// J is the right end of the subsequence
            thisSum+=arrays[j];
            If (thissum > maxsum) maxsum = thissum; // if the sum is greater than the final result, update maxsum.
        };
    }
    return maxSum;
}
Max subseqsum — divide and conquer

Algorithm complexity: t (n) = O (nlgn)

int MaxSubSeqSum(int arrays[], int left, int right) {
    int sum = 0;
    if (left == right) {
        if (arrays[left] > 0)return arrays[left];
        else sum = 0;
    } else {
        int middle = (left + right) / 2;
        int leftSum = MaxSubSeqSum(arrays, left, middle);
        int rightSum = MaxSubSeqSum(arrays, middle + 1, right);
        int finalLeftSum = 0, thisLeftSum = 0;
        for (int i = left; i <=middle; i++) {
            thisLeftSum += arrays[i];
            if (thisLeftSum > finalLeftSum)finalLeftSum = thisLeftSum;
        }
        int finalRightSum = 0, thisRightSum = 0;
        for (int j = middle + 1; j < right; j++) {
            thisRightSum += arrays[j];
            if (thisRightSum > finalRightSum)finalRightSum = thisRightSum;
        }
        sum = finalLeftSum + finalRightSum;
        printf("left sum is %d,right sum is %d\n",finalLeftSum,finalRightSum);
        if (sum < leftSum)sum = leftSum;
        if (sum < rightSum)sum = rightSum;
    }
    return sum;
}
Test main function
int main() {
    int array[] ={1,6,-5,4,2,-3,6};
    int result = MaxSubSeqSum(array,0,7);
    printf("result is %d\n", result);
}
Operation result

In order to facilitate observation, we print out the maximum sum of the largest subsequences obtained on both sides of each time

F:\ClionProject\DataStruct\cmake-build-debug\DataStruct.exe
left sum is 1,right sum is 6
left sum is 0,right sum is 4
left sum is 7,right sum is 0
left sum is 2,right sum is 0
left sum is 6,right sum is 0
left sum is 0,right sum is 6
left sum is 6,right sum is 5
result is 11

Process finished with exit code 0

Linear table is the most basic, simple and commonly used data structure.
The relationship between data elements in a linear table is one-to-one, that is, except for the first and last data elements, all other data elements are connected first and last. For example, the logical level of circular linked list is also a linear table (the storage level belongs to chain storage), but the tail pointer of the last data element points to the first node.

Two storage methods of linear table

  • Sequential storage
  • Linked Storage
Sequential storage of linear tables
typedef struct LinkedList{
    Int data [maxsize]; // store array
    Int last; // cursor pointer
}List;
List * MakeEmpty(){
    List *Ptrl;
    Ptrl=(List *)malloc(sizeof(List));
    Ptrl->Last=-1;
    return Ptrl;
}
/**T(n)=O(N)*/
int FindElement(int result,List* Ptrl){
    int i=0;
    while(i<=Ptrl->Last&&Ptrl->data[i]!=result)
        i++;
    If (I > PTRL - > last) return - 1; // if not found, return - 1
    else return i;
}
void Insert(int result,int i,List *Ptrl){
    int j;
    if(Ptrl->Last==MAXSIZE-1){
        Printf ("table full");
        return;
    }
    if(i<1||i>Ptrl->Last+2){
        Printf ("illegal insertion location");
        return;
    }
    For (J = PTRL - > last; J > = I-1; J --) // move in reverse order (note J > = i-1)
        Ptrl->data[j+1]=Ptrl->data[j];
    PTRL - > data [i] = result; // insert data
    PTRL - > last + +; // last pointer++
    return;
}
/*T(N)=O(N)*/
void DeleteElement(int i,List* Ptrl){
    int j;
    If (I < 1|i > PTRL - > last + 1) {// judge the validity of the location (Note: the list subscript starts from 1)
        Printf ("element% d does not exist", I);
        return;
    }
    For (J = I; J < = PTRL - > last; j + +) // move all elements forward
        Ptrl->data[j-1]=Ptrl->data[j];
    Ptrl->Last--;
    return;
}

Chain storage of linear table

typedef struct LinkedList {
    int data;
    struct LinkedList *next;
} List;

//Find the length of chain list
int Length(List *Ptrl) {
    List *p = Ptrl;
    int j = 0;
    while (p) {
        p = p->next;
        j++;
    }
    return j;
}

//Find by sequence number
List *FindKth(int k, List *Ptrl) {
    List * P = PTRL; // returns the move pointer P without changing the header node
    int i = 1;
    while (p != NULL && i < k) {
        p = p->next;
        i++;
    }
    if (i == k)return p;
    else return NULL;
}

//Find by value
List *Find(int result, List *Ptrl) {
    List *p = Ptrl;
    while (p != NULL && p->data != result)
        p = p->next;
    return p;
}

//Construct new node, application space
//Find the low I-1 node of the list
//Modify pointer insertion node
List *Insert(int result, int i, List *Ptrl) {
    List *p, *s;
    If (I = = 1) {// when the chain list is empty
        s = (List *) malloc(sizeof(List));
        s->data = result;
        s->next = Ptrl;
        return s;
    }
    P = findkth (I - 1, PTRL); // find the I-1 node
    if (p == NULL) {
        Printf ("bad parameter");
        return NULL;
    } else {
        s = (List *) malloc(sizeof(List));
        s->data = result;
        s->next = p->next;
        p->next = s;
        return Ptrl;
    }
}

List *Delete(int i, List *Ptrl) {
    List *p, *s;
    If (I = = 1) {// check whether the first node is to be deleted
        S = PTRL; // s points to the first node
        If (PTRL! = null) PTRL = PTRL - > next; // delete from the linked list
        else return NULL;
        Free (s); // free space
        return Ptrl;
    }
    p = FindKth(i, Ptrl);
    If (P = = null) {// move forward after
        Printf ("input error");
        return NULL;
    } else if (p->next != NULL) {
        s=p->next;
        p->next = s->next;
        Free (s); // clean up unused space
        return Ptrl;
    }
}
Stack (sequential storage) array mode
typedef struct{
    int Data[MAXSIZE];
    int Top;
}Stack;
void Push(Stack *stack,int value){
    If (stack - > Top = = maxsize-1) {// array bounded
        Printf ("stack full");
    }else{
        stack->Data[++(stack->Top)]=value;
        return;
    }
}
int Pop(Stack *stack){
    If (stack - > Top = = - 1) {// is null check
        Printf ("stack is empty");
        return ERROR;
    } else
    return stack->Data[stack->Top--];
}
A bounded array stores two stacks
#define MAXSIZE 50
   /*A bounded array stores two stacks. If there is space in the array, the stack operation is performed. (one grows to the right and one grows to the left)
    * */
   typedef struct DStack{
       int data[MAXSIZE];
       int Top1;
       int Top2;
   }Stacks;
   void Push(Stacks *stacks,int value,int Tag){
       if(stacks->Top2-stacks->Top1==1){
           Printf ("stack full"); return;
       }
       if(Tag==1)
           stacks->data[++stacks->Top1]=value;
       else
           stacks->data[--stacks->Top2]=value;
   }
   int Pop(Stacks *stacks,int Tag){
       if(Tag==1){
           if(stacks->Top1==-1){
               Printf ("stack 1 empty");
               return NULL;
           }else {
               return stacks->data[stacks->Top1--];
           }
       }else{
           if(stacks->Top2==MAXSIZE){
               Printf ("stack 2 empty");
               return NULL;
           }else{
               return stacks->data[stacks->Top2++];
           }
       }
   }
   int main() {
       Stacks *stacks;
       stacks->Top1=-1;
       Stacks - > top2 = maxsize; // initialize two stack head pointers
       return 0;
   }

Stack (chain store)

/*When a stack is represented by a one-way linked list, the stack top node must be a chain head node.
 * */
typedef struct Node{
    int value;
    struct Node *next;
}LinkedStack;
LinkedStack * CreateLinkedStack(){
    LinkedStack *stack;
    stack=(LinkedStack *)malloc(sizeof(LinkedStack));
    stack->next=NULL;
    return stack;
};
Int isempty (linkedstack * stack) {// note that the top node has no value, only the header pointer of a single chain table
    return (stack->next==NULL);
}
void Push(LinkedStack *stack,int value){
    LinkedStack *insertElement;
    Insertelement = malloc (sizeof (linkedstack)); // allocate memory space
    Insertelement - > value = value; // the inserted value is assigned to the node.
    Insertelement - > next = stack - > next; // link the existing linked list to the inserted node
    Stack - > next = insertelement; // change the top node
}
int Pop(LinkedStack *stack){
    int result;
    LinkedStack *popElement;
    if(isEmpty(stack)){
        Printf ("the list is empty");
        return ERROR;
    }else{
        popElement=stack->next;
        result=popElement->value;
        stack->next=popElement->next;
        Free (popelement); // remember to free up useless memory space
        return result;
    }
}

How to convert infix expression to suffix expression
Read every object of infix expression from beginning to end

  • 1. Operand: direct output
  • 2. Left bracket: push into stack
  • 3. Right parenthesis: pop up the operator at the top of the stack and output it until the left parenthesis is encountered (no output after stack exit)
  • 4. Operator:
    If the priority is greater than the stack top operator, stack pressing
    If the priority is less than or equal to the stack top operator, pop up the stack top operator.

Then compare the new stack top operator until the modified operator is higher than the stack top operator priority, and then press the stack.

  • 5. If the objects have been processed, output the remaining operators in the stack together.

Stack Usage:

  • Function call and recursive implementation
  • Depth first search
  • Backtracking algorithm
Queues (sequential storage)
#define MAXSIZE 50
typedef struct {
    int value[MAXSIZE];
    int rear;
    int front;
}Queue;
Queue *CreateQueue(){
    Queue *queue;
    queue=(Queue *)malloc(sizeof(Queue));
    queue->front=0;
    queue->rear=0;
    return queue;
}
void AddQueue(Queue *queue,int value){
    if((queue->rear+1)%MAXSIZE==queue->front){
        printf("queue is full");
        return;
    }else {
        queue->rear=(queue->rear+1)%MAXSIZE;
        queue->value[queue->rear] = value;
    }
}
int IsEmpty(Queue *queue){
    if(queue->rear==queue->front)return 1;
    else return 0;
}
void OutQueue(Queue* queue,int *value){
    if(IsEmpty(queue)){
        printf("Queue is empty");
        return;
    }else{
        queue->front=(queue->front+1)%MAXSIZE;
        *value=queue->value[queue->front];
    }
}

Queue (chain storage) note

typedef struct Node {
    int value;
    struct Node *next;
} QNode;
typedef struct {
    QNode *rear;
    QNode *front;
} Queue;

void InitQueue(Queue **queue) {
    QNode *p;
    p = (QNode *) malloc(sizeof(QNode));
    p->next = NULL;
    (*queue)->front = p;
    (*queue)->rear = p;
}

void InQueue(Queue *queue, int value) {
    QNode *InElement;
    InElement = (QNode *) malloc(sizeof(QNode));
    InElement->value = value;
    InElement->next = NULL;
    queue->rear->next = InElement;
    queue->rear = InElement;
}

int IsEmpty(Queue *queue) {
    if (queue->rear = queue->front)return 1;
    else return 0;
}

void OutQueue(Queue *queue, int *value) {
    QNode *OutElement;
    if (IsEmpty(queue)) {
        printf("queue is empty");
        return;
    } else {
        OutElement = queue->front->next;
        Queue - > front - > next = outelement - > next; // the pointer head node points to the next node (psppspsps)
        *value=OutElement->value;
        free(OutElement);
        If (isempty (queue)) {// if the queue is empty, it will be set to empty queue.
            queue->front=queue->rear;
        }
    }
}

Decision tree

The number of times each node needs to be searched is exactly the number of layers where the node is located. When the search is successful, the number of searches will not exceed the depth of the decision tree. The depth of the decision tree of N nodes is [LGN] + 1

Average search length
A finite set of ASL = sum (number of layers * number) / total number of layers n (n > = 0) nodes is called an empty tree when n = 0

For any non empty tree (n > 0), it has the following properties

  • There will be a special root node in the tree represented by R
  • The rest nodes can be divided into m (M > 0) disjoint finite sets, each of which is a tree itself, called the subtree of the original tree

Tree features:

  • Subtrees are disjoint
  • Out of the root node, every node has only one parent node
  • A tree with n nodes has n-1 edges (a tree is the least edge linking way to ensure node connectivity)

Some basic terms of trees:

  • Degree of node: number of subtrees of node (degree of single node of full binary tree is 2)
  • Degree of tree: the maximum degree of all nodes in the tree
  • Leaf node: node with node degree 0
  • Parent node, child node, brother node
  • Path and path length
  • Ancestor node: all nodes in the path from tree root to a node are ancestor nodes of this node
    The offspring are connected with each other.
  • Node level: Specifies that the root node is in one level, and other levels follow the child node + 1
  • Depth of the tree: the largest level of nodes in the tree is the depth of the tree

    Son brother notation can transform all trees into binary trees

Special binary tree:

  • Diagonal binary tree: only left son or right node
  • Perfect binary tree: full binary tree
  • Complete binary tree: the node number is the same as that of full binary tree (the number is continuous)

Characteristics of binary tree

  • The maximum number of nodes in the i-th layer of a binary tree is: 2 (i-1), I > = 1
  • The maximum number of nodes in the depth K binary tree is 2k-1, k > = 1.
  • For any non empty binary tree T, if N0 represents the number of leaf nodes and N2 is the number of non leaf nodes with degree 2, then the two satisfy the relationship: N0 = N2 + 1; (that is, the number of leaf nodes – 1 = the number of nodes with degree 2)

Abstract data type definition of binary tree
Data object set: a finite set of nodes
If it is not empty, it consists of the root node and its left and right binary trees
Operation set: judge whether the tree is empty, traverse, and create a binary tree

Common traversal methods include:
First order traversal (left and right roots),
Middle order traversal (left root right),
Backward traversal (left and right roots),
Hierarchical traversal (top to bottom, left to right)

In a binary tree, we know that the relationship between the total number of leaf nodes N0 and the total number of nodes N2 with two sons is: N0 = N2 + 1.
Can similar relations be extended to m-tree? That is, if the total number of leaf nodes in m-tree is N0,
The total number of nodes with one son is N1, the total number of nodes with two sons is N2, and the total number of nodes with three sons is N3.
So, what is the relationship between Ni?

  • Complete binary tree, the parent node sequence number of non root node is [I / 2]
  • If 2I < = n, there is no left child node.
  • The serial number of the right child node of the node is 2I + 1, (if 2I + 1 < = n, otherwise there is no right child)
typedef struct BT{
     int value;
     struct BT *leftchild;
     struct BT *rightchild;
 }BinTree;
 //Each node of a binary tree will be traversed three times. The first time it is printed is the first order traversal, the second time it is printed is the middle order traversal, and the third time it is printed is the post order traversal.
 //Preorder traversal (recursive traversal)
 void PreOrderTraversal(BinTree *BT){
     if(BT){
     if(!BT->leftchild&&!BT->rightchild)
         printf("%d\n",BT->value);
         PreOrderTraversal(BT->leftchild);
         PreOrderTraversal(BT->rightchild);
     }
 }
 //Middle order traversal (recursive traversal)
 void InOrderTraversal(BinTree *BT){
     if(BT){
     if(!BT->leftchild&&!BT->rightchild)
         InOrderTraversal(BT->leftchild);
         printf("%d\n",BT->value);
         InOrderTraversal(BT->rightchild);
     }
 }
 //Postorder traversal (recursive traversal)
 void PostOrderTraversal(BinTree *BT){
     if(BT){
     if(!BT->leftchild&&!BT->rightchild)
         PostOrderTraversal(BT->leftchild);
         PostOrderTraversal(BT->rightchild);
         printf("%d\n",BT->value);
     }
 }
 //The essence of binary tree traversal is to transform two-dimensional sequence into one-dimensional sequence
 //Use queue to access binary tree hierarchically (traverse root node and put left and right child nodes into queue)
 void LevelOrderTraversal(BinTree BT){
     Queue *queue;
     BinTree *T;
     queue=CreateQueue();
     AddQueue(queue,BT);
     while(!IsEmptyQueue(queue)){
         T=DeleteQueue(queue);
         printf("%d\n",T->value);
         if(T->leftchild)AddQueue(queue,T->leftchild);
         if(T->rightchild)AddQueue(queue,T->rightchild);
     }
 }
 //Given the result of pre middle order traversal or post middle order traversal, a binary tree can be uniquely determined.
 //Non recursive implementation (middle order traversal)
 void InOrderTraversal(BinTree *BT){
     BinTree *T=BT;
     Linkedstack * stack = createlinkedstack(); // create and initialize the stack
     while(T||!isEmpty(stack)){
         While (T) {// push the nodes along the way all the way to the left onto the stack
             Push(stack,T);
             T = t - > leftchild; // turn to the left subtree
         }
         if(!isEmpty(stack)){
             T = pop (stack); // the node pops up the stack
             Printf (""% 5D ", T - > value); // print node
             T = t - > rightchild; // turn to the right subtree
         }
     }
 }
 //Nonrecursive implementation (sequential traversal)
 void PreOrderTraversal(BinTree *BT){
     BinTree *T=BT;
     Linkedstack * stack = createlinkedstack(); // create and initialize the stack
     while(T||!isEmpty(stack)){
         While (T) {// push the nodes along the way all the way to the left onto the stack
             Printf (""% 5D ", T - > value); // print node
             Push(stack,T);
             T = t - > leftchild; // turn to the left subtree
         }
         if(!isEmpty(stack)){
             T = pop (stack); // the node pops up the stack
             T = t - > rightchild; // turn to the right subtree
         }
     }
 }
Binary search tree: BST (binary search tree)

Also known as binary sort tree or binary search tree
Binary search tree conditions

1. All key values of non empty left subtree are less than the key values of its root node.
   2. All key values of non empty right subtree are greater than the key values of its root node.
   3. Left and right subtrees are binary search trees
//Recursive implementation
Position Find(BinTree *binTree,int result){
    if(!binTree)return NULL;
    if(result>binTree->value)return Find(binTree->rightchild,result);
    else if(result<binTree->value)return Find(binTree,result);
    Else return bintree; // the search succeeds. The node address is returned (return tail recursion).
}
//Non recursive implementation
Position IterFind(BinTree *binTree,int value){
    while(binTree){
        if(result>binTree->value)
            binTree=binTree->rightchild;
        else if(result<binTree->value)
            binTree=binTree->leftchild;
        else 
            return binTree;
    }
    return NULL;
}
//Find minimum
Position FindMin(BinTree *binTree){
    if(!binTree)return NULL;
    else if(!binTree->leftchild)
        return binTree;
    else
        return FindMin(binTree->leftchild);
}
//Find maximum
Position FindMax(BinTree *binTree){
    if(binTree){
        while(binTree->rightchild)
            binTree=binTree->rightchild;
    }
    return binTree;
}
//Node insertion
BinTree * Insert(BinTree *binTree, int value) {
    if(!binTree){
        binTree=malloc(sizeof(BinTree));
        binTree->value=value;
        binTree->leftchild=binTree->rightchild=NULL;
    }else{
        if(value<binTree->value)
            binTree->leftchild=Insert(binTree->leftchild,value);
        else if(value>binTree->value)
            binTree->rightchild=Insert(binTree->rightchild,value);
    }
    return binTree;
}
//Delete node
BinTree *Delete(BinTree *binTree,int value){
    (Position)BinTree *Temp;
    If (! Bintree) printf ("element to be deleted not found");
        //Recursive deletion of left subtree
    else if(value<binTree->value)binTree->leftchild=Delete(binTree,value);
        //Recursive deletion of right subtree
    else if(value>binTree->value)binTree->rightchild=Delete(binTree->rightchild,value);
    Else // find the node to delete
        If (bintree - > leftchild & & bintree - > rightchild) {// the deleted node has left and right quantum children
            Temp = findmin (bintree - > rightchild); // fill the delete node with the smallest element in the right subtree
            binTree->value=Temp->value;
            binTree->rightchild=Delete(binTree->rightchild,binTree->value);
        }Else {// the deleted node has one or no child nodes
            Temp=binTree;
            if(!binTree->leftchild)binTree=binTree->rightchild;
            else if(!binTree->rightchild)binTree=binTree->leftchild;
            free(Temp);
        }
    return binTree;
}
Balanced binary tree

(AVL tree) (AVL is the initial of the scholar who proposed the balanced tree)

  • The height difference between the left and right subtrees of an empty tree or any node is no more than 1|bf (T) | < 1
  • Balance factor (BF: BF (T) = HL HR)
  • Where HL and HR are the height of left and right subtrees of T respectively
  • Height = number of floors – 1
  • The height of complete binary tree is log2n (balanced binary tree)
  • NH is the minimum node tree of a balanced binary tree of H height
  • Nh=F(h+2)-1
#define MaxData 10000
 typedef struct HeapStruct{
     Int * value; // stores an array of elements
     Int length; // the current number of elements in the heap
     Int capacity; // maximum heap capacity
 }Heap;
Priority queue

The order in which the elements are retrieved is based on the priority (key) of the elements, not the order in which the elements are queued
Both the maximum heap and the minimum heap must satisfy the establishment of the maximum heap of the complete binary tree

Build the maximum heap: store the existing n elements in the one-dimensional array according to the requirements of the maximum heap

  • Method 1: insert n elements into an initial empty heap one by one, with the maximum time cost of O (nlogn)
  • Method 2: building the maximum heap in linear time complexity

    • (1) store n elements in the input order, and first satisfy the structural characteristics of the complete binary tree
    • (2) adjust the position of each node to meet the ordered characteristics of the largest reactor
      In the worst case, the number of elements to be moved is equal to the sum of the height of each node in the tree.

For the binary search tree (search tree) and the minimum heap composed of the same N integers, the following conclusions are obtained

  • The height of binary search tree is greater than or equal to the minimum heap height
  • The middle order traversal of the binary search tree can get the sequence from small to large.
  • The node values on the path from the minimum heap root node to any leaf node constitute a sequence from small to large
Heap * Create(int MaxSize){
     Heap *heap=malloc(sizeof(Heap));
     heap->value=malloc((MaxSize+1)*sizeof(int));
     heap->length=0;
     heap->capacity=MaxSize;
     Heap - > value [0] = MAXDATA; // define sentinel, easy to operate
     return heap;
 }
 void Insert(Heap *heap,int value){
     int i;
     if(IsFull(heap)){
         Printf ("the maximum heap is full");
         return;
     }
     i=++heap->length;
     for(;heap->value[i/2]<value;i/=2)
         heap->value[i]=heap->value[i/2];
     heap->value[i]=value;
 }
 int DeleteMax(Heap *heap){
     int parent,child;
     int maxValue,temp;
     if(IsEmpty(heap)){
         Printf ("maximum heap empty");
         return 0;
     }
     maxValue=heap->value[1];
     //Filter the lower level nodes from the root node with the last element in the maximum heap
     temp=heap->value[heap->length--];
     for(parent=1;parent*2<=heap->length;parent=child){
         child=parent*2;
         //The node of left son and right son is larger
         if((child!=heap->length)&&(heap->value[child]<heap->value[child+1]))
             child++;
         if(temp>=heap->value[child])break;
         else
             heap->value[parent]=heap->value[child];
     }
     heap->value[parent]=temp;
     return maxValue;
 }
 int IsEmpty(Heap *heap){
     return heap->length==0;
 }
 int IsFull(Heap *heap){
     return heap->length==heap->capacity;
 }
 
 typedef struct TreeNode{
     int weight;
     struct TreeNode *left,*right;
 }HuffmanTree;
Huffman tree

Search efficiency, search times times times search probability
Weighted path length (WPL)If a binary tree has n leaf nodes, each leaf node has a weight wk, and the length from the root node to each leaf node is LK, then the sum of the total path length of each leaf node WPL = (nek = 1) wklk
Optimal binary tree or Huffman tree: WPL minimum binary tree
Characteristics of Huffman tree

  • No node with degree 1
  • The Huffman tree with n leaf nodes has 2N-1 nodes
  • The left and right subtrees of any non leaf node of Huffman tree are still Huffman tree after exchanging
    For a set of weights, there may be two Huffman trees of different structures

    HuffmanTree *Huffman(Heap *heap){
        //Suppose that the heap - > length weight already exists in the heap - > value [] - > weight.
        int i;HuffmanTree *huffmanTree;
        Buildheap (heap); // adjust heap - > value [] to the minimum heap by weight
        for(i=1;i<heap->length;i++){
            Huffman tree = malloc (sizeof (Huffman tree)); // create a new node
            HuffmanTree - > left = deletemin (heap); // delete a node from the minimum heap as the left child of the new HuffmanTree
            Humantree - > right = deletemin (heap); // delete a node from the minimum heap as the right child of the new humantree
            Humantree - > weight = humantree - > weight + humantree - > right - > weight; // calculate new // weight
            Insert(heap,huffmanTree);
        }
        huffmanTree=DeleteMin(heap);
        return huffmanTree;
    }
    /*Binary tree for coding
     *When the encoded letters are all in the leaf node of the binary tree (that is, the encoded letters will not appear in the node with child nodes), it can ensure that the character code has no ambiguity.
I happened to see such a question in a book, and I thought it was meaningful to listen to it, so I used it to do it. The question is set in this way.
**Two linear tables (A1, A2, A3, A4... A m), (B1, B2, B3... BN), (B1, B2, B3, B3... BN) are stored in a known one-dimensional array a [M + n], and try to write a function to exchange the positions of the two order tables, that is, from (a, 1, A2, A2, A3, A3, A3, A4... Am, B1, B2, B2, B3... BN ` to '(B1, B2, B3, B3... BN, a, 1, A2, A3, A4... Am ` requires o (1) space complexity * I think this problem will often appear in interview questions, ha ha ha ha, ha, ha, ha, ha, ha, ha, ha, ha, ha, ha, ha, ha, A4... Am ` to' convert ` to '(B1, B2, B3, B3... BN, B3... BN, a, a, a, A2, A3 far away, here's me The level of the answer is limited. If there is any mistake, please don't hesitate to comment.


At first glance, the problem is quite troublesome. The sizes of the two arrays are different. It is not easy to control the number of in-situ reverse loops. To reorganize the idea, we found that it can be realized in three steps with a very clever method.
Step 1: reverse the letter sequence
Part 2: reverse the number sequence
Part three: invert the whole array
**The inverse function is as follows:**
The inversion function needs two parameters, which are the starting position [start] and the ending position [End] of the array to be inverted.
Public static void reverse (int start, int end) {// reverse function
    char temp;
    while(start<end) {
        temp = array[start];
        array[start++] = array[end];
        array[end--] = temp;
    }
}
tip:*char array[]={'A','B','C','D','E','F','G','H','1','2','3','4'}*
Test array a [0-7], B [8-11]

**The test results are as follows:**
![image.png](https://imgs.developpaper.com/imgs/2480310-05c78f4d0acc3395.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/640)


###Full code

public class Main {

public static char array[]={'A','B','C','D','E','F','G','H','1','2','3','4'};
public static void main(String[] args) {
    Reverse (0,7); // reverse the alphabet sequence to hgfedcba1234
    Reverse (8,11); // the result of reverse digit sequence is: hgfedcba4321
    Reverse (0,11); // the overall reverse result is: 1234abcdefg
    print(array);
}
Public static void reverse (int start, int end) {// reverse function
    char temp;
    while(start<end) {
        temp = array[start];
        array[start++] = array[end];
        array[end--] = temp;
    }
}
private static void print(char[] array) {
    for (int i = 0; i <array.length; i++)
        System.out.print(array[i]);
    System.out.println();
}

}

###Queen n's question

/**

  • n queens problem

*

  • */

public class EightQueen {

private int QUEEN_COUNT = 0;//represent the queen count
private int[][] queenCount;//chess box matrix
private int resultCount = 0;//solution number
private int[] queenPlace;//mark the queen placed position
/**
 * construct a EightQueen with a argument represent the number of queen
 * initial a empty chess box
 * 0 represent empty
 * 1 represent the area has been taken
 * recurse to call the putQueen method
 * the queenPlace array to mark the queen's taken area which uses to print
 *
 * */
public EightQueen(int n) {
    this.QUEEN_COUNT = n;
    this.resultCount = 0;
    this.queenCount = new int[QUEEN_COUNT][QUEEN_COUNT];
    queenPlace = new int[QUEEN_COUNT];
    putQueen(0);
}
/**
 * implement the putQueen function to recursion
 * use column index in outer loop and row index in inner loop with step increase
 * */
private void putQueen(int row) {
    for (int column = 0; column < QUEEN_COUNT; column++) {//loop for QUEEN_COUNT times
        if (queenCount[row][column] == 0) {//judge the condition
            /**
             * each row has one queen
             * mark the column and diagonal back diagonal(row has been scatter)
             *
             * */
            for (int nextRow = row + 1; nextRow < QUEEN_COUNT; nextRow++) {
                queenCount[nextRow][column]++;
                if (column - nextRow + row >= 0) {
                    queenCount[nextRow][column - nextRow + row]++;
                }
                if (column + nextRow - row < QUEEN_COUNT) {
                    queenCount[nextRow][column + nextRow - row]++;
                }
            }
            queenPlace[row] = column;//place the queen with only column information
            if (row == QUEEN_COUNT - 1) printQueen(++resultCount);//recursion has completed
            else putQueen(row + 1);//recurse to call the putQueen function
            /**
             *
             * unmarked the column and diagonal back diagonal(row has been scatter)
             *
             * */
            for (int rows = row + 1; rows < QUEEN_COUNT; rows++) {
                queenCount[rows][column]--;
                if (column - rows + row >= 0) {
                    queenCount[rows][column - rows + row]--;
                }
                if (column + rows - row < QUEEN_COUNT) {
                    queenCount[rows][column + rows - row]--;
                }
            }
        }
    }
    if (row == 0) System.out.println(QUEEN_COUNT + " queens has totally " + resultCount + "result.");
}

private void printQueen(int size)
{
    System.out.println("********** "+size+" **********\n");
    for (int i = 0; i < QUEEN_COUNT; i++) {
        for (int j = 0; j < QUEEN_COUNT; j++) {
            System.out.print(queenPlace[i] == j ? " # " : " - ");
        }
        System.out.println();
    }
}

}

###Priority queue

/**

  • use maximum-top heap to implement priority queue
  • define a MAX_SIZE_OF_PRIORITY_QUEUE to limit the max length of priority queue
  • use a integer array to store element
  • hypothesis i is the root node and then use 2i to mark left child and 2i+1 to mark right child
  • use initialArray[0] to store the length of heap
  • */

public class PriorityQueue{

private static final int MAX_SIZE_OF_PRIORITY_QUEUE=100;
private int[] initialArray;
/**
 * initial priority queue with a exist array which can't be null
 * */
public PriorityQueue(int[] initialElement) {
    if(initialElement==null)return;
    if(initialElement.length==0)return;
    initialArray=new int[MAX_SIZE_OF_PRIORITY_QUEUE];
    initialArray[0]=initialElement.length;
    for(int i=0;i<initialElement.length;i++)initialArray[i+1]=initialElement[i];
    System.out.println(initialArray[0]);
    for (int i = initialArray[0]; i >0 ; i--)reBuildHeap(i);
}
/**
 * rebuild array according to the value of each node
 * maximum-top heap
 * index represents the index of a node which should be rebuild(include it's children node)
 *
 * simple:
 *         1
 *      2     3
 *   4   5  6   7
 *
 * */
private void reBuildHeap(int index){
    System.out.println("execute rebuild function to rebuild a maximum-top heap with one loop");
    int leftChildIndex=index*2;
    int rightChildIndex=leftChildIndex+1;
    int length=initialArray[0];
    int biggerValueIndex=-1;
    if(leftChildIndex>length&&rightChildIndex>length){
        System.out.println("no left child");
        return;
    }
    if(leftChildIndex<=length&&rightChildIndex>length){
        System.out.println("only left child");
        biggerValueIndex=leftChildIndex;
    }
    if(leftChildIndex>length&&rightChildIndex<=length){
        System.out.println("only right child");
        biggerValueIndex=rightChildIndex;
    }
    if(leftChildIndex<=length&&rightChildIndex<=length){
        System.out.println("both children");
        biggerValueIndex=initialArray[leftChildIndex]>initialArray[rightChildIndex]?leftChildIndex:rightChildIndex;
    }
    if(initialArray[index]>initialArray[biggerValueIndex]){
        System.out.println("unnecessary to swap!");
        return;
    }else{
        int temp=initialArray[index];
        initialArray[index]=initialArray[biggerValueIndex];
        initialArray[biggerValueIndex]=temp;
        this.reBuildHeap(biggerValueIndex);
    }
}
public int getLength() {
    return initialArray[0];
}
/**
 * get top priority value of heap
 * the first element of array
 * */
public int priority(){
    return initialArray[1];
}
/**
 * length++
 * add element to the tail of array
 * rebuild the heap to regular priority heap
 * */
public void insert(int element){
    initialArray[0]++;
    initialArray[initialArray[0]]=element;
    for(int i=initialArray[0];i>=1;i=i/2){
        reBuildHeap(i);
    }
}
/**
 * length--
 * swap the first element and last element
 * delete last value
 * rebuild the heap
 * */
public int deletePriority(){
    if(initialArray[0]<=0)return -1;
    int maxValue=initialArray[1];
    initialArray[1]=initialArray[initialArray[0]];
    initialArray[0]--;
    for(int i=initialArray[0];i>=1;i=i/2){
        reBuildHeap(i);
    }
    return maxValue;
}
/**
 * print the structure of priority heap
 * */
@Override
public String toString() {
    StringBuilder builder=new StringBuilder("{");
    for (int i = 1; i <= initialArray[0]; i++) {
        if(i!=1)builder.append(",");
        builder.append(initialArray[i]);
    }
    builder.append("}");
    return builder.toString();
}

}