上次写了一个二叉树的创建的程序,代码思想基本都是数据结构书本上的,后面看到另外一个人的博客 用java实现了一个二叉排序树的转换为双向链表的程序,代码之多吓我一跳,后面想想用递归的方法从二叉树的基础上按照某种方式建立双向链表,代码量应该不是很多。
- #define EQ(x,m) ( x == m ? 1 : 0)
- #define LT(x,m) ( x < m ? 1 : 0)
- typedef int Element;
- typedef struct tag_Tree
- {
- Element data;
- struct tag_Tree * lchild;
- struct tag_Tree * rchild;
- }*BiTree,BiTNode;
- typedef struct tag_DuLNode
- {
- Element data;
- struct tag_DuLNode * next;
- struct tag_DuLNode * prior;
- }*DulList,DulNode;
- /*按插入的方式建立二叉排序树*/
- int InsertBST(BiTree * T , Element e)
- {
- BiTree s,p;
- if( !SearchBST(*T,e,0,&p) )
- {
- s = (BiTree) malloc( sizeof(BiTNode) );
- s -> data = e;
- s -> lchild = s -> rchild = 0;
- if( ! p ) *T = s;
- else if ( LT(e,p->data))
- {
- p -> lchild = s;
- }
- else
- {
- p -> rchild = s;
- }
- return 1;
- }
- else
- return 0;
- }
- /*从排序树中删除 元素为e的节点,递归搜索,然后搜索删除*/
- int DeleteBST(BiTree * T,Element e)
- {
- if(!(*T))
- {
- return 0;
- }
- else
- {
- if( EQ(e,(*T)->data) )
- {
- return DeleteSearch(T);
- }
- else if( LT(e,(*T)->data) )
- {
- return DeleteBST(&((*T)->lchild),e);
- }
- else
- return DeleteBST(&((*T)->rchild),e);
- }
- }
- /*
- 从排序树中删除的节点T
- 如果节点的左子树为空,就用右子树待地该节点
- 如果节点的右子树为空,就用左子树待地该节点
- 如果,T节点的左右孩子都不为空,则取T左孩子的最右孩子代替该节点,
- (如果T的左子树没有右孩子,则直接用T的左孩子的左孩子代替为T的左孩子)
- */
- int DeleteSearch(BiTree* T)
- {
- BiTree q,s;
- if(!(*T))
- return 0;
- if( ! (*T)->lchild )
- {
- q = *T;
- (*T) = (*T)->rchild;
- free(q);
- }
- else if( ! (*T)->rchild)
- {
- q = *T;
- (*T) = (*T)->lchild;
- free(q);
- q=0;
- }
- else
- {
- q = (*T);
- s = (*T) -> lchild;
- while( s ->rchild )
- {
- q = s;
- s = s->rchild;
- }
- (*T)->data = s ->data;
- if ( q != (*T)) q->rchild = s ->lchild;
- else
- {
- q ->lchild = s ->lchild;
- }
- free(s);
- }
- }
- int SearchBST(BiTree T,Element key,BiTree f,BiTree * p)
- {
- if(!T)
- {
- *p = f;
- return 0;
- }
- else if( EQ(key,T->data) )
- {
- *p = T;
- return 1;
- }
- else if( LT(key,T->data) )
- {
- return SearchBST(T->lchild,key,T,p);
- }
- else
- {
- return SearchBST(T->rchild,key,T,p);
- }
- }
- /*构造新的双向链表的节点*/
- DulNode * NewChainNode(Element data)
- {
- DulNode * pChain=0;
- pChain = ( DulNode * )malloc( sizeof(DulNode) );
- if( ! pChain ) return 0;
- pChain->data=data;
- pChain->next=0;
- pChain->prior=0;
- return pChain;
- }
- /*得到链表上的某个点,pos 为-1得到最后一个*/
- DulNode * GetAddr(DulList plist,int pos)
- {
- DulNode * pt = 0;
- int n = 0 ;
- if( !(plist ) || pos < -1 )
- return 0;
- pt = plist;
- if( pos == -1)
- {
- while(pt->next)
- {
- pt = pt->next;
- }
- return pt;
- }
- while(n < pos)
- {
- pt = pt->next;
- n++;
- }
- return pt;
- }
- /*
- 递归创建:
- 按递增的方式创建双向链表
- ,创建完成之后会在链表的最后有个数值为0的无效节点,小小的缺憾,有待改进;
- */
- int CreateList_Dul_Ins(BiTree T,DulList * DList)
- {
- DulNode * newp = 0;
- DulNode * oldp = 0;
- Element data= 0;
- if(!T)
- return 0 ;
- if(!( DList))
- return 0;
- newp =GetAddr(*DList,-1);
- CreateList_Dul_Ins(T->lchild,&(newp)) ;
- /*printf("%d ",T->data);*/
- newp =GetAddr(*DList,-1);
- newp->data = T->data;
- newp ->next = NewChainNode(data);
- newp ->next->prior = newp;
- newp = newp->next;
- CreateList_Dul_Ins(T->rchild,&(newp) ) ;
- return 1;
- }
- /*
- 递归创建:
- 按递增的方式创建双向链表
- ,创建完成之后会在链表的最后有个数值为0的无效节点,小小的缺憾,有待改进;
- */
- int CreateList_Dul_Des(BiTree T,DulList * DList)
- {
- DulNode * newp = 0;
- DulNode * oldp = 0;
- Element data= 0;
- if(!T)
- return 0 ;
- if(!( DList))
- return 0;
- newp = * DList ;
- CreateList_Dul_Des(T->lchild,&(newp)) ;
- * DList = newp;
- /*printf("%d ",T->data);*/
- newp->data = T->data;
- oldp = NewChainNode(data);
- oldp->next = newp;
- newp->prior = oldp;
- (* DList) = oldp;
- newp = * DList ;
- if( CreateList_Dul_Des(T->rchild,&(newp) ) )
- {
- * DList = newp;
- }
- return 1;
- }
- void showTree(BiTree T)
- {
- if(!T) return ;
- printf("%d ", T->data);
- showTree(T->lchild);
- showTree(T->rchild);
- }
- /*两种方式输出双向链表*/
- void showList(DulList DList)
- {
- DulList pt;
- pt =DList;
- printf("\n");
- printf("正向输出: ");
- while(pt)
- {
- printf("%d ",pt->data);
- pt = pt->next;
- }
- printf("\n");
- printf("反向输出: ");
- /*后续输出*/
- pt = GetAddr(DList,-1);
- while(pt)
- {
- printf("%d ",pt->data);
- pt = pt->prior;
- }
- printf("\n");
- }
- main()
- {
- int a[20]={45,24,53,12,37,90,-2};//"hello world!";
- int n = 0;
- BiTree T = 0;
- BiTree f = 0;
- BiTree p = 0;
- DulList ADList =NewChainNode(0); /* 双向链表的头结点*/
- DulList BDList =NewChainNode(0);
- /*建立二叉排序树*/
- while( a[n] > 0)
- {
- InsertBST(&T , a[n]);
- n++;
- }
- showTree(T);
- printf("\n");
- if(! SearchBST(T,53,0,&p) )
- printf("error\n");
- /* DeleteBST(&T,24);
- */
- printf("输出二叉排序树,先根序\n");
- showTree(T);
- printf("\n");
- CreateList_Dul_Des(T,&(ADList));
- showList(ADList);
- printf("\n");
- CreateList_Dul_Ins(T,&(BDList));
- showList(BDList);
- }