1, Linear table
1. Reverse all elements in the sequence table
Algorithm idea: the first element and the last element are swapped, the second element and the penultimate element are swapped,..., and so on.
void Reverse(int A[], int n) { int i, t; for (i=0; i < n/2; i++) { t = A[i]; A[i] = A[n-i-1]; A[n-i-1] = t; } }
2. Delete all nodes in the linear linked list whose data field is item
Algorithm idea: start from the second node of the linked list and judge whether all nodes in the linked list meet the conditions from front to back. If the data field of a node is item, delete the node. Finally, go back to judge whether the first node in the linked list meets the conditions. If so, delete it.
void PurgeItem(LinkList &list) { LinkList p, q = list; p = list->next; while (p != NULL) { if (p->data == item) { q->next = p->next; free(p); p = q->next; } else { q = p; p = p->next; } } if (list->data == item) { q = list; list = list->next; free(q); } }
3. Reverse linear linked list
void Reverse(LinkList &list) { LinkList p, q, r; p = list; q = NULL; while (p != NULL) { r = q; q = p; p = p->next; q->next = r; } list = q; }
4. Copy linear linked list (recursive)
LinkList Copy(LinkList lista) { LinkList listb; if (lista == NULL) return NULL; else { listb = (LinkList)malloc(sizeof(LNode)); listb->data = lista->data; listb->next = Copy(lista->next); return listb; } }
5. Merge two non empty linear linked lists ordered by value into one linear linked list ordered by value
LinkList MergeList(LinkList lista, LinkList listb) { LinkList listc, p = lista, q = listb, r; // listc points to the smaller of the nodes referred to by lista and listb if (lista->data <= listb->data) { listc = lista; r = lista; p = lista->next; } else { listc = listb; r = listb; q = listb->next; } while (p != NULL && q != NULL) { if (p->data <= q->data) { r->next = p; r = p; p = p->next; } else { r->next = q; r = q; q = q->next; } } // Link the remaining nodes (that is, the nodes that have not participated in the comparison and are arranged in ascending order) to the back of the whole linked list r->next = (p != NULL) ? p : q; return listc; }
2, Tree
1. Preorder traversal of binary tree (non recursive algorithm)
Algorithm idea: if the node referred to by p is not empty, access the node, then put the address of the node on the stack, and then point p to its left child node; If the node pointed to by p is empty, exit the top element of the stack (the address of a node) from the stack and point p to its right child node. Repeat the above process until p = NULL and the stack is empty, and the traversal ends.
#define MAX_STACK 50 void PreOrderTraverse(BTree T) { BTree STACK[MAX_STACK], p = T; int top = -1; while (p != NULL || top != -1) { while (p != NULL) { VISIT(p); STACK[++top] = p; p = p->lchild; } p = STACK[top--]; p = p->rchild; } }
2. Middle order traversal of binary tree (non recursive algorithm)
Algorithm idea: if the node referred to by p is not empty, put the address p of the node on the stack, and then point p to its left child node; If the node pointed to by p is empty, exit the stack top element (the address of a node) from the stack and send it to p, access the node, and then point p to the right child node of the node. Repeat the above process until p = NULL and the stack is empty, and the traversal ends.
#define MAX_STACK 50 void InOrderTraverse(BTree T) { BTree STACK[MAX_STACK], p = T; int top = -1; while (p != NULL || top != -1); { while (p != NULL) { STACK[++top] = p; p = p->lchild; } p = STACK[top--]; VISIT(p); p = p->rchild; } }
3. Post order traversal of binary tree (non recursive algorithm)
Algorithm idea: when p points to a node, it cannot be accessed immediately, but its left subtree should be accessed first, so the address of this node should be put on the stack; After the left subtree is accessed, when the node is searched again (the node address is obtained by de stacking), it cannot be accessed, and its right subtree needs to be accessed first. Therefore, the address of the node is stacked again. Only when the right subtree of the node is accessed and returns to the node can the node be accessed. In order to indicate whether a node can be accessed, a flag variable flag is introduced. When flag = 0, it means that the node is not accessed temporarily, and when flag = 1, it means that the node can be accessed. The value of flag is put on and out of the stack together with the address of the node. Therefore, two stacks are set in the algorithm, in which STACK1 stores the address of the node and STACK2 stores the flag variable flag. The two stacks use the same stack top pointer, and the initial value of top is − 1.
#define MAX_STACK 50 void PostOrderTraverse(BTree T) { BTree STACK1[MAX_STACK], p = T; int STACK2[MAX_STACK], flag, top = -1; while (p != NULL || top != -1) { while (p != NULL) { STACK1[++top] = p; STACK2[top] = 0; p = p->lchild; } p = STACK1[top]; flag = STACK2[top--]; if (flag == 0) { STACK1[++top] = p; STACK2[top] = 1; p = p->rchild; } else { VISIT(p); p = NULL; } } }
4. Traversal by hierarchy of binary tree
Algorithm idea: set a queue, first put the root node (address) into the queue, and then exit an element from the queue in turn. For each element exiting, first access the node referred to by the element, and then put the left child node (if any) and right child node (if any) of the node into the queue in turn. This is repeated until the queue is empty.
#define MAX_QUEUE 50 void LayeredOrderTraverse(BTree T) { BTree QUEUE[MAX_QUEUE], p; int front, rear; if (T != NULL) { QUEUE[0] = T; front = -1; rear = 0; while (front < rear) { p = QUEUE[++front]; VISIT(P); if (p->lchild != NULL) QUEUE[++rear] = p->lchild; if (p->rchild != NULL) QUEUE[++rear] = p->rchild; } } }
5. Establish a binary tree (input data from the keyboard and traverse the recursive algorithm first)
BTree CreateBT() { char ch; BTree T; sacnf("%c", &ch); if (ch == ' '){ return NULL; } else { T = (BTree)malloc(sizeof(BTNode)); T->data = ch; T->lchild = CreateBT(); T->rchild = CreateBT(); return T; } }
6. Establish binary tree (get data from array)
BTree CreateBT(int A[], int i, int n) { BTree p; if (i > n){ return NULL; } else { p = (BTree)malloc(sizeof(BTNode)); p->data = A[i]; p->lchild = CreateBT(A, 2*i, n); p->rchild = CreateBT(A, 2*i+1, n); return p; } } T = CreateBT(A, 1, n); -------------------------------------------------------- BTree CreateBT(int A[], int n) { int i; BTree *pT; // Corresponding to N nodes, apply for memory space that can accommodate n pointer variables pT = (BTree *)malloc(sizeof(BTree)*n); // If an element in the array is not equal to zero, the corresponding node space is applied and assigned for (i=1; i <= n; i++) { if (A[i] != 0) { pT[i] = (BTree)malloc(sizeof(BTNode)); pT[i]->data = A[i]; } else { pT[i] = NULL; } } // Modify the contents of the pointer field of the node so that the parent node points to the left and right child nodes for (i=1; i <= n; i++) { if (pT[i] != NULL) { pT[i]->lchild = pT[2*i]; pT[i]->rchild = pT[2*i+1]; } } }
- Find the depth of binary tree (recursive algorithm)
int Depth(BTree T) { int ldepth, rdepth; if (T == NULL){ return 0; } else { ldepth = Depth(T->lchild); rdepth = Depth(T->rchild); if (ldepth > rdepth){ return ldepth+1; }else { return rdepth+1; } } }
8. Find the depth of binary tree (non recursive algorithm)
Algorithm idea: traverse the binary tree, and record the number of layers of each node and the maximum number of layers of nodes that have been visited. Whenever a leaf node is accessed, the number of layers in which the leaf node is located is compared with the maximum number of layers. If the former is greater than the latter, the maximum number of layers is modified to the number of layers of the leaf node, otherwise it will not be modified. At the end of traversal, the maximum number of recorded layers is the depth of the binary tree. This algorithm uses a non recursive middle order traversal algorithm (other traversal sequences can also be used).
#define MAX_STACK 50 int Depth(BTree T) { BTree STACK1[MAX_STACK], p = T; int STACK2[MAX_STACK]; int curdepth, maxdepth = 0, top = -1; if (T != NULL) { curdepth = 1; while (p != NULL || top != -) { while (p != NULL) { STACK1[++top] = p; STACK2[top] = curdepth; p = p->lchild; curdepth++; } p = STACK1[top]; curdepth = STACK2[top--]; if (p->lchild == NULL && p->rchild == NULL) { if (curdepth > maxdepth){ maxdepth = curdepth; p = p->rchild; curdepth++; } } } } return maxdepth; }
9. Find the level of the node
Algorithm idea: the non recursive algorithm of post order traversal is used to traverse the binary tree. In the traversal process, each node is judged whether it is a qualified node. If it is a qualified node, the number of elements saved in the stack plus 1 is the level of the node.
#define MAX_STACK 50 int LayerNode(BTree T, int item) { BTree STACK1[MAX_STACK], p = T; int STACK2[MAX_STACK], flag, top = -1; while (p != NULL || top != -1) { while (p != NULL) { STACK1[++top] = p; STACK2[top] = 0; p = p->lchild; } p = STACK1[top]; flag = STACK2[top--]; if (flag == 0) { STACK1[++top] = p; STACK2[top] = 1; p = p->rchild; } else { if (p->data == item) return top+2; p = NULL; } } }
10. Exchange the positions of the left and right subtrees of all nodes in the binary tree
Algorithm idea: traverse the binary tree according to the hierarchy. In the traversal process, whenever a node is accessed, the positions of the left and right subtrees of the node are switched.
#define MAX_QUEUE 50 void ExchangeBT(BTree T) { BTree QUEUE[MAX_QUEUE], temp, p = T; int front, rear; if (T != NULL) { QUEUE[0] = T; front = -1; rear = 0; while (front < rear) { p = QUEUE[++front]; temp = p->lchild; p->lchild = p->rchild; p->rchild = temp; if (p->lchild != NULL){ QUEUE[++rear] = p->lchild; } if (p->rchild != NULL) { QUEUE[++rear] = p->rchild; } } } }
11. Delete the subtree with a node as the root node in the binary tree
Algorithm idea: first traverse to find the qualified node (other traversal methods can also be used), and then delete the subtree with this node as the root node. Finally, set the corresponding pointer field of the parent node of the node to NULL. Therefore, it is necessary to set a pointer variable in the algorithm to indicate the parent node of the current node.
#define MAX_STACK 50 BTree DeleteSubtree(BTree &T, int item) { BTree STACK[MAX_STACK], q, p = T; int top = -1; if (T->data == item){ DestroyBT(T); T = NULL; return NULL; } else { while (p != NULL || top != -1){ while (p != NULL){ if (p->data == item){ if (q->lchild == p){ q->lchild = NULL; }else { q->rchild = NULL; DestroyBT(p); return T; } } STACK[++top]= p; q = p; p = p->lchild; } q = STACK[top--]; p = q->rchild; } } }
3, Search
1. Recursive algorithm of sequential search
int RecurSeqSearch(int A[], int n, int key, int i) { if (i >= n) return -1; if (A[i] == key) return i; else return RecurSeqSearch(A, n, key, i+1); } pos = RecurSeqSearch(A, n, key, 0);
2. Half search
int BinSearch(int A[], int n, int key){ int low=0, high=n-1, mid; while (low <= high){ mid = (low+high)/2; if (key == A[mid]){ return mid; if (key > A[mid]){ low = mid + 1; else high = mid – 1; } return -1; } } }
3. Recursive algorithm of half search
int RecurBinSearch(int A[], int low, int high, int key){ int mid; if (low > high){ return -1; }else { mid = (low+high)/2; if (key == A[mid]){ return mid; } if (key > A[mid]) { return RecurBinSearch(A, mid+1, high, key); else return RecurBinSearch(A, low, mid-1, key); } } } pos = RecurBinSearch(A, 0, n-1, key);
4. Find and insert an element in half in the linear table with length n arranged by increasing value
void BinInsert(int A[], int &n, int key){ int j, low=0, high=n-1, mid; while (low <= high) { mid = (low+high)/2; if (key > A[mid]){ low = mid + 1; else high = mid – 1; } } for (j=n; j > low; j--){ A[j] = A[j-1]; A[low] = key; n++; } }
5. In the linear table arranged by increasing value and with length of n, find the smallest element whose value is not less than key by half
void BinSearch(int A[], int n, int key){ int low=0, high=n-1, mid; while (low <= high){ mid = (low+high)/2; if (key == A[mid]){ return mid; } if (key > A[mid]){ low = mid + 1; } else{ high = mid – 1; } } if (low <= n-1) { return low; } else { return -1; } }
4, Sort
1. Insert sort
Algorithm idea: the i-th insertion sequence is: insert an element into the ordered subsequence containing I − 1 elements to make it an ordered subsequence containing I elements. In the process of finding the insertion position, you can move the elements back at the same time. The whole process is to insert n − 1 times, that is, the first element of the whole sequence is regarded as ordered, and then insert one by one from the second element until the whole sequence is ordered.
void InsertSort(int A[], int n){ int i, j, temp; for (i=1; i <= n-1; i++){ if (A[i] < A[i-1]){ j = i-1; temp = A[i]; } while (j >= 0 && temp < A[j]){ A[j+1] = A[j]; j--; } A[j+1] = temp; } }
2. Sort by half insertion
Algorithm idea: the algorithm is the same as direct insertion sorting, but uses the half search method to find the insertion position.
void BinInsertSort(int A[], int n){ int i, j, low, high, mid, temp; for (i=1; i <= n-1; i++){ temp = A[i]; low= 0; high = i – 1; while (low <= high){ mid = (low+high)/2; if (temp > A[mid]){ low = mid + 1; }else high = mid – 1; } for (j=i; j > low; j--) A[j] = A[j-1]; A[low] = temp; } }
3. Bubble sorting
Algorithm idea: first compare the first element with the second element. If the former is greater than the latter, they exchange positions, and then compare the second element with the third element. And so on until the n − 1st element and the nth element are compared or exchanged. The above process is called one trip bubble sorting, and the result is that the element with the largest value in n elements is arranged at the position of the last element. Then perform the second sorting, that is, perform the same operation on the first n − 1 element, so that the element with the largest value in the first n − 1 element is arranged at the n − 1 position. Generally, the i-th bubbling sequence starts from the first element in the previous n − i + 1 element, and compares them. If the former is greater than the latter, it is exchanged. As a result, the largest element in the first n − i + 1 element is arranged in the n-th element
− i + 1 position. Obviously, the condition for judging the end of bubble sorting is that "there is no exchange element operation in one sorting". Therefore, set a flag variable flag. Flag = 1 indicates that there has been exchange element operation, and flag = 0 indicates that there has been no exchange element operation. Before the beginning of each sorting, set the flag to 0. In the sorting process, as long as there is exchange element operation, Set the flag to 1 in time. Because at least one sorting operation must be performed, flag = 1 for the first sorting.
void BubbleSort(int A[], int n){ int i, j, temp, flag = 1; for (i=n-1; i >= 1 && flag == 1; i--){ flag = 0; //Flag indicating whether the bubble exchange occurs in this trip for (j=0; j < i; j++){ //Indicates bubbling if (A[j] > A[j+1]){ //If in reverse order temp = A[j]; //exchange A[j] = A[j+1]; A[j+1] = temp; flag = 1; } } } }
4. Quick sort
Algorithm idea: select any element (usually called boundary element or benchmark element) in the sequence participating in sorting, move all elements less than or equal to the boundary element to the front of the boundary element, and move all elements greater than the boundary element to the back of the boundary element. In this way, the current sequence participating in sorting is divided into two subsequences, All elements in the previous subsequence are smaller than all elements in the latter subsequence, and the boundary element is just in the final position of sorting. Then, the above sorting process is carried out recursively for the two subsequences respectively, until all elements are in the final position of sorting, and the sorting ends.
void QuickSort(int A[], int n){ QSort(A, 0, n-1); } void QSort(int A[], int low, int high){ int pivotloc; if (low < high){ pivot = Partition(A, low, high); QSort(A, low, pivotloc-1); QSort(A, pivotloc+1, high); } } int Partition(int A[], int low, int high){ int pivot; pivot = A[low]; // Scan alternately from both ends of the linear table to the middle while (low < high){ while (low < high && A[high] >= pivot) high--; A[low] = A[high]; while (low < high && A[low] <= pivot) low++; A[high] = A[low]; } A[low] = pivot; return low; }
5. Select Sorting
Algorithm idea: the i-th sorting selects an element with the smallest value from the last n − i + 1 (i = 1, 2,..., n − 1) elements of the sequence to exchange positions with the first element of the element, that is, with the i-th element of the whole sequence. And so on until i = n − 1. In other words, each sort selects an element with the lowest value from those elements that have not been ordered, and then exchanges its position with the first element of these elements that have not been ordered.
void SelectSort(int A[], int n){ int i, j, min, temp; for (i=0; i < n; i++){ min = i; for (j=i+1; j < n; j++){ if (A[min] > A[j]) min = j; } if (min != i){ temp = A[min]; A[min] = A[i]; A[i] = temp; } } }
6. Heap sorting
void HeapSort(int A[], int n){ int i, temp; // Build large top reactor for (i = n/2; i >= 1; i--) HeapAdjust(A,i,n); for (i = n-1; i >= 1; i--){ temp = A[1]; A[1] = A[i+1]; A[i+1] = temp; // Readjust A[1..i] to large top stack HeapAdjust(A,1,i); } } void HeapAdjust(int A[], int low, int high){ int i, temp; temp = A[low]; for (i=2*low; i <= high; i=i*2){ // Make i the subscript of the record with larger keyword if (i < high && A[i] < A[i+1]){ i++; }else if (temp >= A[i]) { break; } else if { A[low] = A[i]; low = i; } } A[low] = temp; // insert }