Data Structure-sequential storage of Binary Trees in C Language
// Sequential storage of Binary Trees // use the cyclic queue to store data // Yang Xin # include
# Include
# Include
# Include
# Define MAXQSIZE 5 // maximum queue length (for cyclic queues, the maximum queue length must be reduced by 1) # define MAX_TREE_SIZE 100 // maximum number of nodes of a binary tree # define ClearBiTree InitBiTree // In the sequential storage structure, the two functions are exactly the same as typedef char TElemType; typedef TElemType SqBiTree [MAX_TREE_SIZE]; // unit 0: storage root node typedef int QElemType; TElemType Nil = ''; // layer intorder of the node where the blank space character typedef struct {int level; // The serial number of the current layer (calculated based on the full Binary Tree)} position; typedef struct {QElemType * base; // The initial Dynamic Allocation of storage space is equivalent to an array int fro Nt; // header pointer. If the queue is not empty, it points to the queue Header element, which is equivalent to an array subscript int rear; // tail pointer. If the queue is not empty, point to the next position of the end element of the queue // equivalent to an array subscript} SqQueue; // construct an empty binary tree T. Because T is a fixed array and does not change, you do not need & int InitBiTree (SqBiTree T) {int I; for (I = 0; I
= 0; I --) // locate the last node if (T [I]! = Nil) break; I ++; // to facilitate calculation of doj ++; while (I> = pow (2, j); // I> pow (2, depth-1) & I <= pow (2, depth) return j; // j = depth;} // when T is not empty, use e to return the root of T, 1 is returned; otherwise, 0 is returned. e is not defined. int Root (SqBiTree T, TElemType * e) {if (BiTreeEmpty (T) // T is null. return 0; else {* e = T [0]; return 1 ;}// return the TElemType Value (SqBiTree T, position e) {// convert the sequence numbers of the layer and the current layer to the return T [(int) pow (2, e. level-1)-1) + (e. order-1)]; // (int) pow (2, e. level-1 )- 1) for the e. number of levels, // (e. order-1) location of the current layer} // Assign a value int Assign (SqBiTree T, position e, TElemType value) to the node in the position e (layer, local serial number) {// convert the sequence numbers of the layer and the current layer to the int I = (int) pow (2, e. level-1) + e. order-2; if (value! = Nil & T [(I + 1)/2-1] = Nil) // If the leaf is not null, but the parent is empty, return 0; else if (value = Nil & (T [I * 2 + 1]! = Nil | T [I * 2 + 2]! = Nil) // The Null value of the parent and the return 0; T [I] = value; return 1;} // if e is a non-root node of T, returns its parents. Otherwise, "null" TElemType Parent (SqBiTree T, TElemType e) {int I; if (T [0] = Nil) is returned) // empty tree return Nil; for (I = 1; I <= MAX_TREE_SIZE-1; I ++) if (T [I] = e) // find the left child of e return T [(I + 1)/2-1]; return Nil; // No e} // return e. If e has no left child, return "null" TElemType LeftChild (SqBiTree T, TElemType e) {int I; if (T [0] = Nil) // empty tree return Nil; for (I = 0; I <= MAX_TREE_SIZE-1; I ++) if (T [I] = e) // find the right child of e return T [I * 2 + 1]; return Nil; // No e} // return e. If e has no right child, "null" TElemType RightChild (SqBiTree T, TElemType e) {int I; if (T [0] = Nil) is returned) // empty tree return Nil; for (I = 0; I <= MAX_TREE_SIZE-1; I ++) if (T [I] = e) // find e return T [I * 2 + 2]; return Nil; // No e} // return the Left brother of e. If e is a left child of T or has no left brother, "null" TElemType LeftSibling (SqBiTree T, TElemType e) {int I; if (T [0] = Nil) is returned) // empty tree return Nil; for (I = 1; I <= MAX_TREE_SIZE-1; I ++) if (T [I] = e & I % 2 = 0) // find e and its serial number is an even number (is the right child) return T [I-1]; return Nil; // No e} // return the right brother of e. If e is the right child of T or has no right brother, "null" TElemType RightSibling (SqBiTree T, TElemType e) {int I; if (T [0] = Nil) is returned) // empty tree return Nil; for (I = 1; I <= MAX_TREE_SIZE-1; I ++) if (T [I] = e & I % 2) // find e and its serial number is odd (left child) return T [I + 1]; return Nil; // failed to find e} // shift the subtree starting from j node of q to the subtree starting from I node of T // InsertChild () void Move (SqBiTree q, int j, SqBiTree T, int I) {if (q [2 * j + 1]! = Nil) // The left subtree of q is not empty Move (q, (2 * j + 1), T, (2 * I + 1 )); // move the left subtree of the j node of q to the left subtree of the I node of T if (q [2 * j + 2]! = Nil) // The right subtree of q is not empty Move (q, (2 * j + 2), T, (2 * I + 2 )); // shift the right subtree of the j node of q to the right subtree of the I node of T [I] = q [j]; // shift q's j node to T's I node q [j] = Nil; // leave q's j node Blank} // according to LR's 0 or 1, insert c into the left or right subtree of the p node in T. The original left or right subtree of the p node becomes the right subtree of c int InsertChild (SqBiTree T, TElemType p, int LR, SqBiTree c) {int j, k, I = 0; for (j = 0; j <(int) pow (2, BiTreeDepth (T)-1; j ++) // search for the p sequence number if (T [j] = p) // The j is the p sequence number break; k = 2 * j + 1 + LR; // if (T [k]! = Nil) // p the original left or right child is not empty Move (T, k, T, 2 * k + 2 ); // Move the subtree starting from k node of T to Move (c, I, T, k) from the right subtree of k node ); // shift the subtree starting from the I node of c to return 1 from the k node of T;} // construct an empty queue Qint InitQueue (SqQueue * Q) {(* Q ). base = (QElemType *) malloc (MAXQSIZE * sizeof (QElemType); // allocate a fixed-length space, equivalent to an array if (! (* Q ). base) // storage allocation failure exit (0); (* Q ). front = (* Q ). rear = 0; // initialize the subscript return 1;} // Insert the new team end element int EnQueue (SqQueue * Q, QElemType e) whose Element e is Q) {if (* Q ). rear> = MAXQSIZE) {// when the queue is full, add one storage unit (* Q ). base = (QElemType *) realloc (* Q ). base, (* Q ). rear + 1) * sizeof (QElemType); if (! (* Q ). base) // failed to add the unit return 0;} * (* Q ). base + (* Q ). rear) = e; (* Q ). rear ++; return 1 ;}// if the queue is not empty, delete the queue Header element of Q, use e to return its value, and return 1, otherwise, 0 int DeQueue (SqQueue * Q, QElemType * e) {if (* Q) is returned ). front = (* Q ). rear) // The return 0; * e = (* Q) is empty in the queue ). base [(* Q ). front]; (* Q ). front = (* Q ). front + 1; return 1;} // Delete the left or right subtree int DeleteChild (SqBiTree T, position p, int LR) {int I; int k = 1; // indicates that the queue is not empty. SqQueue q; InitQueue (& q); // initialize the queue, used to store the node to be deleted I = (Int) pow (2, p. level-1) + p. order-2; // convert the sequence numbers of layers and layers into the matrix sequence number if (T [I] = Nil) // return 0 is empty for this node; I = I * 2 + 1 + LR; // the serial number of the root node of the subtree to be deleted in the matrix while (k) {if (T [2 * I + 1]! = Nil) // EnQueue (& q, 2 * I + 1) is not empty on the left node; // if (T [2 * I + 2] of the Left node to join the queue! = Nil) // EnQueue (& q, 2 * I + 2) is not empty on the right node; // The number of the right node T [I] = Nil; // Delete this node k = DeQueue (& q, & I); // The queue is not empty} return 1;} int (* VisitFunc) (TElemType ); // function Variable void PreTraverse (SqBiTree T, int e) {// PreOrderTraverse () calls VisitFunc (T [e]); // call the VisitFunc function to process the root if (T [2 * e + 1]! = Nil) // The left subtree is not empty PreTraverse (T, 2 * e + 1); // then process the left subtree if (T [2 * e + 2]! = Nil) // The right subtree is not empty PreTraverse (T, 2 * e + 2);} // traverses T in the first order, and calls the Visit function for each node once and only once. Int PreOrderTraverse (SqBiTree T, int (* Visit) (TElemType) {VisitFunc = Visit; if (! BiTreeEmpty (T) // The tree is not empty PreTraverse (T, 0); printf ("\ n"); return 1 ;}// InOrderTraverse () calls void InTraverse (SqBiTree T, int e) {if (T [2 * e + 1]! = Nil) // The left subtree is not empty. InTraverse (T, 2 * e + 1); VisitFunc (T [e]); if (T [2 * e + 2]! = Nil) // The right subtree is not empty. InTraverse (T, 2 * e + 2);} // traverses T in the middle order, and calls the Visit function for each node once and only once. Int InOrderTraverse (SqBiTree T, int (* Visit) (TElemType) {VisitFunc = Visit; if (! BiTreeEmpty (T) // The tree is not empty. InTraverse (T, 0); printf ("\ n"); return 1 ;}// PostOrderTraverse () calls void PostTraverse (SqBiTree T, int e) {if (T [2 * e + 1]! = Nil) // The left subtree is not empty PostTraverse (T, 2 * e + 1); if (T [2 * e + 2]! = Nil) // The right subtree is not empty PostTraverse (T, 2 * e + 2); VisitFunc (T [e]);} // The back-order traversal T, call the Visit function for each node once and only once. Int PostOrderTraverse (SqBiTree T, int (* Visit) (TElemType) {VisitFunc = Visit; if (! BiTreeEmpty (T) // PostTraverse (T, 0); printf ("\ n"); return 1 ;}// sequence traversal Binary Tree void LevelOrderTraverse (SqBiTree T, int (* Visit) (TElemType) {int I = MAX_TREE_SIZE-1, j; while (T [I] = Nil) I --; // locate the sequence number of the last non-empty node for (j = 0; j <= I; j ++) // start from the root node, traverse Binary Tree by sequence if (T [j]! = Nil) Visit (T [j]); // only traverse non-empty node printf ("\ n ");} // output the binary tree void Print (SqBiTree T) {int j, k; position p; TElemType e; for (j = 1; j <= BiTreeDepth (T); j ++) {printf ("% d layer:", j); for (k = 1; k <= pow (2, j-1); k ++) {p. level = j; p. order = k; e = Value (T, p); if (e! = Nil) printf ("% d: % c", k, e);} printf ("\ n") ;}} int visit (TElemType e) {printf ("% c", e); return 0 ;}int main () {int I, j; position p; TElemType e; SqBiTree T, s; initBiTree (T); CreateBiTree (T); printf ("is the tree empty after a binary tree is created? % D (1: YES 0: No) depth of the tree = % d \ n ", BiTreeEmpty (T), BiTreeDepth (T); I = Root (T, & e); if (I) printf ("the root of the binary tree is % c \ n", e); elseprintf ("tree blank, rootless \ n "); printf ("sequence traversal Binary Tree: \ n"); LevelOrderTraverse (T, visit); printf ("middle order traversal Binary Tree: \ n"); InOrderTraverse (T, visit ); printf ("post-order traversal of Binary Tree: \ n"); PostOrderTraverse (T, visit); printf ("Enter the layer number of the node to be modified :"); scanf ("% d % * c", & p. level, & p. order); e = Value (T, p); printf ("the original Value of the node to be modified is % c. enter a new Value:", e ); scanf ("% c % * c", & e); Assign (T, p, e ); Printf ("first-order traversal of a binary tree: \ n"); PreOrderTraverse (T, visit); printf ("Node % c has two parents: % c, and the left and right children are respectively", e, parent (T, e); printf ("% c, % c, left and right brothers are", LeftChild (T, e), RightChild (T, e )); printf ("% c, % c \ n", LeftSibling (T, e), RightSibling (T, e); InitBiTree (s ); printf ("Create a tree with an empty right subtree s: \ n"); CreateBiTree (s); printf ("insert tree s into tree T, enter the parent node s of tree T to left (0) or right (1) subtree: "); scanf (" % c % d % * c ", & e, & j); InsertChild (T, e, j, s); Print (T); printf ("delete subtree, enter the layer number of the Child root node to be deleted. The layer number is left (0) or right (1 :" ); Scanf ("% d % * c", & p. level, & p. order, & j); DeleteChild (T, p, j); Print (T); ClearBiTree (T); printf ("after clearing a binary tree, is the tree empty? % D (1: YES 0: No) depth of the tree = % d \ n ", BiTreeEmpty (T), BiTreeDepth (T); I = Root (T, & e); if (I) printf ("the root of the binary tree is % c \ n", e); elseprintf ("tree blank, rootless \ n "); return 0 ;}
: