CCI_Q4.4----给定一棵二叉查找树,设计算法,将每一层的所有结点构建为一个链表(也就是说, 如果树有D层,那么你将构建出D个链表)
本文参考该作者文章当作编程笔记: 作者:Hawstein 出处:http://hawstein.com/posts/ctci-solutions-contents.html
Q:
给定一棵二叉查找树,设计算法,将每一层的所有结点构建为一个链表(也就是说, 如果树有D层,那么你将构建出D个链表)
思路:
定义一个保存链表头节点指针的数组,现将2叉树跟节点放入到数组p_nl[0]中,跟节点层就一个节点,跟节点层链表构建完毕。
进行循环,遍历已构造的链表,将链表中的节点的孩子节点插入到新链表。最后,直到遍历完叶子节点链表。链表全部构造完成。
其中有不相关的代码。
CODE:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<limits.h> 4 #define N 9 /*树的结点数*/ 5 #define key(A) (A) 6 #define less(A,B) (A<B) 7 /*树的结构*/ 8 typedef struct node 9 { 10 char item; 11 struct node *l,*r; 12 }node; 13 /*链表结构*/ 14 typedef struct node_link 15 { 16 node *node_item; 17 struct node_link * next; 18 }node_link; 19 /*存放链表头指针的数组*/ 20 node_link *p_nl[N]; 21 /*链表数组的索引*/ 22 int p_nl_i=0; 23 /*插入链表用的尾指针*/ 24 node_link *p_tail=NULL; 25 /*初始化链表头节点*/ 26 void nodeLinkInit(node_link **head) 27 { 28 *head=(node_link *)malloc(sizeof(node_link)); 29 (*head)->next=NULL; 30 } 31 /*链表新节点*/ 32 node_link * nodeLinkNew(node *node_item,node_link *next) 33 { 34 node_link *x=(node_link *)malloc(sizeof(node_link)); 35 x->node_item=node_item; 36 x->next=next; 37 return x; 38 } 39 /*通过全局变量尾指针,在链表尾部插入新节点*/ 40 void insertNodeLink(node *node_item) 41 { 42 p_tail->next=nodeLinkNew(node_item,p_tail->next); 43 p_tail=p_tail->next; 44 } 45 /*层次遍历2叉树,将孩子节点插入新的链表*/ 46 void traverseLevel(node *h) 47 { 48 /*先初始化2叉树跟节点层的链表*/ 49 nodeLinkInit(&p_nl[p_nl_i]); 50 /*将尾指针指向链表头节点*/ 51 p_tail=p_nl[p_nl_i]; 52 insertNodeLink(h); /*将2叉树跟节点插入新的链表*/ 53 /*如果指向链表的指针为空,说明已经到达叶子节点的下一层,跳出循环*/ 54 while(p_nl[p_nl_i]->next) 55 { 56 nodeLinkInit(&p_nl[p_nl_i+1]); 57 p_tail=p_nl[p_nl_i+1]; 58 node_link *nl_cur=p_nl[p_nl_i]; /*本层的链表头节点*/ 59 /*只要本层链表不到尾指针,继续构造孩子节点新链表*/ 60 while(nl_cur->next) 61 { 62 nl_cur=nl_cur->next; 63 if(nl_cur->node_item->l!=NULL) 64 insertNodeLink(nl_cur->node_item->l); 65 if(nl_cur->node_item->r!=NULL) 66 insertNodeLink(nl_cur->node_item->r); 67 } 68 ++p_nl_i; 69 } 70 } 71 /*构造2叉树*/ 72 void insertNode(node **h,char *s,int start,int end) 73 { 74 int mid=(start+end)/2; 75 if(start>end) 76 return; 77 (*h)=(node *)malloc(sizeof(node)); 78 (*h)->item=s[mid]; 79 (*h)->l=NULL; 80 (*h)->r=NULL; 81 insertNode(&((*h)->l),s,start,mid-1); 82 insertNode(&((*h)->r),s,mid+1,end); 83 } 84 /*打印2叉树*/ 85 void printfNode(char item,int blank) 86 { 87 int i; 88 for(i=0;i<blank;++i) 89 printf(" "); 90 printf("%c\n",item); 91 } 92 void traversePre(node *h,int blank) 93 { 94 if(h==NULL) 95 {printfNode('*',blank); return;} 96 printfNode(h->item,blank); 97 traversePre(h->l,blank+1); 98 traversePre(h->r,blank+1); 99 } 100 int max=INT_MIN,min=INT_MAX,hight=0; 101 /*根节点为第1层,当到达叶子节点时,判断是否为最大、最小高度*/ 102 void traversePreMaxMin(node *h) 103 { 104 if(h==NULL) 105 return; 106 ++hight; 107 traversePreMaxMin(h->l); 108 traversePreMaxMin(h->r); 109 if(h->l==NULL && h->r==NULL) 110 { 111 if(max<hight) 112 max=hight; 113 if(min>hight) 114 min=hight; 115 } 116 --hight; 117 } 118 /*打印链表*/ 119 void displayNodeLink(node_link *h) 120 { 121 while(h->next) 122 { 123 h=h->next; 124 printf("%c\t",h->node_item->item); 125 } 126 putchar('\n'); 127 } 128 int main() 129 { 130 node *head=NULL; 131 char s[]="ABCDEFBYZ"; 132 insertNode(&head,s,0,N-1); /*取有序数组中间的元素,当作根,递归插入*/ 133 traversePre(head,0); /*前序遍历树*/ 134 printf("%d\t%d\n",max,min); /*max和min初始值*/ 135 traversePreMaxMin(head); /*找出树的最大、最小高度*/ 136 printf("%d\t%d\n",max,min); /*输出最大、最小高度*/ 137 traverseLevel(head); 138 int i; 139 for(i=0;i<p_nl_i;i++) 140 displayNodeLink(p_nl[i]); 141 return 0; 142 }
问题:
指针、链表还是有问题,在参数传递过程中,需不需要传递指向指针的指针,传递指向指针的指针有什么好处,还是不太明白。