• 链表节点面试100题系列之1将查找二叉树转换成有序的双向链表


    在写这篇文章之前,xxx已经写过了几篇关于改链表节点主题的文章,想要了解的朋友可以去翻一下之前的文章

        1、将二元找查树转化成序排的双向链表,标题起源:

        http://blog.csdn.net/v_JULY_v/article/details/6057286

        10

        / \

        6 14

        / \ / \

        4 8 12 16 => 4<=>6<=>8<=>10<=>12<=>16

        要求:不能创立节点,只变改针指的指向

        法方:其实就是树的中序遍历。用递归的法方build树,然后再将遍历到的节点一个一个的加到链表中去。

    #include<stdio.h>
    #include<string.h>
    struct NODE
    {
    	int data;
    	NODE *Left;
    	NODE *Right;
    };
    const int N = 20;
    NODE node[N];
    int top;
    void Add(NODE *root, int v)
    {
    	if(!root)
    		return;
    	if(root->data < v)
    	{
    		if(root->Right)
    			Add(root->Right, v);
    		else
    		{
    			root->Right = &node[++top];
    			node[top].data = v;
    		}
    	}
    	else if(root->data > v)
    	{
    		if(root->Left)
    			Add(root->Left, v);
    		else
    		{
    			root->Left = &node[++top];
    			node[top].data = v;
    		}
    	}
    	else
    		printf("重复参加节点%d\n", v);	
    }
    //转化后之链表是降序排列的
    NODE *TransTreeToLink(NODE *root)
    {
    	if(!root)
    		return NULL;
    	NODE *stack[N];
    	int top = -1;
    	NODE *p = root;
    	NODE *head = NULL;
    	while(p != NULL || top > -1)
    	{
    		while(p != NULL)
    		{
    			stack[++top] = p;
    			p = p->Left;
    		}
    		if(top > -1)
    		{
    			p = stack[top]->Right;
    			if(!head)
    				head = stack[top];
    			else
    			{
    				//现实与链表的链接,先连,后断
    				stack[top]->Left = head;
    				head->Right = stack[top];
    				head = stack[top];
    			}
    			--top;		
    		}
    	}
    	return head;
    }
    //打印链表
    void Print(NODE *head)
    {
    	if(!head)
    		return;
    	NODE *p;
    	p = head;
    	while(p != NULL)
    	{
    		printf("%d ",p->data);
    		p = p->Left;
    	}
    	printf("\n");
    }
    
    int main()
    {
    	int n,i,v;
    	NODE *head;
    	while(scanf("%d", &n) != EOF)
    	{
    		memset(node, 0, sizeof(node));
    		top = 0;
    		scanf("%d", &v);
    		node[0].data = v;
    		for(i = 1; i < n; ++i)
    		{
    			scanf("%d", &v);
    			Add(&node[0], v);
    		}
    		head = TransTreeToLink(&node[0]);
    		Print(head);
    	}
    }

        PS:附上前以写得很挫的码代:两个关于NODE的定义都是一样的。

        每日一道理
    漫漫人生路,谁都难免会遭遇各种失意或厄运。在凄风苦雨 惨雾愁云的考验面前,一个强者,是不会向命运低头的。风再冷,不会永远不息;雾再浓,不会经久不散。风息雾散,仍是阳光灿烂。
    /*****************************************************************************
    *1、将二元找查树转化成序排的双向链表
    *			  10
    *			 /  \
    *			6	 4
    *		   / \  / \
    *		  4  8 12 16  => 4<=>6<=>8<=>10<=>12<=>16
    *要求:不能创立节点,只变改针指的指向
    *法方:递归和栈。其实就是树的中序遍历。
    ******************************************************************************/
    //将节点参加树间中
    bool AddNodeToTree(TREENODE* &pRoot, int Value)
    {
    	if(NULL == pRoot)
    	{
    		TREENODE *pTemp;
    		pTemp = (TREENODE *)malloc(sizeof(TREENODE));
    		if(NULL == pTemp)
    		{
    			printf("参加节点%d失败。", Value);
    		}
    		pTemp->Data = Value;
    		pTemp->left = NULL;
    		pTemp->right = NULL;
    		pRoot = pTemp;
    		return true;
    	}
    	if(Value < pRoot->Data)
    	{
    		AddNodeToTree(pRoot->left, Value);	
    	}
    	else if(Value > pRoot->Data)
    	{	
    		AddNodeToTree(pRoot->right, Value);
    	}
    	else
    	{
    		printf("重复参加节点%d\n", Value);
    		return false;
    	}
    }
    //将节点转化成有序链表
    TREENODE *TransTreeToLink(TREENODE *pRoot)
    {
    	if(!pRoot)
    	{
    		return NULL;
    	}
    
    	TREENODE *pTemp;
    	//录记链表中的头结点
    	TREENODE *pList = NULL;
    	TREENODE *Stack[MAX_SIZE];
    	int top = -1;
    	
    	//将根节点的左、右及自己入栈
    	if(pRoot->right != NULL)
    	{
    		Stack[++top] = pRoot->right;
    	}
    	Stack[++top] = pRoot;
    	if(pRoot->left != NULL)
    	{
    		Stack[++top] = pRoot->left;
    	}
    
    	while(top > -1)
    	{
    		pTemp = Stack[top];
    		--top;
    		if(NULL == pTemp->left && NULL == pTemp->right)
    		{
    			//如果是第一个进入链表的节点
    			pTemp->left = pList;
    			if(pList != NULL)
    			{
    				pList->right = pTemp;
    			}
    
    			//判断是不是栈中只有最后一个节点未入链表
    			if(top >= 0)
    			{
    				//链表和树之间的连接
    				pTemp->right = Stack[top];
    				Stack[top]->left = pTemp;
    				//更新链头表节点
    				pList = Stack[top];
    				--top;
    			}
    			else
    			{
    				pList = pTemp;
    			}
    		}//end if(NULL == pTemp->left && NULL == pTemp->right)
    		//如果不是第一个入链表的节点
    		else
    		{
    			if(pTemp->right != NULL)
    			{
    				Stack[++top] = pTemp->right;
    			}
    			Stack[++top] = pTemp;
    			if(pTemp->left != NULL)
    			{
    				Stack[++top] = pTemp->left;
    			}	
    		}//end else
    	}//end while(top > -1)
    	return pList;
    }
    //打印链表
    void Print(TREENODE *pList)
    {
    	if(pList ==NULL)
    	{
    		return;
    	}
    	TREENODE *pTemp;
    	pTemp = pList;
    	while(pTemp != NULL)
    	{
    		printf("%d\t", pTemp->Data);
    		pTemp = pTemp->left;
    	}
    }
    //销毁链表
    void Destroy(TREENODE *pList)
    {
    	if(pList == NULL)
    	{
    		return;
    	}
    	TREENODE *pTemp;
    	
    	while(pList != NULL)
    	{
    		pTemp = pList;
    
    		pList = pList->left;
    		free(pTemp);
    		pTemp = NULL;		
    	}
    }

    文章结束给大家分享下程序员的一些笑话语录: 《诺基亚投资手机浏览器UCWEB,资金不详或控股》杯具了,好不容易养大的闺女嫁外国。(心疼是你养的吗?中国创业型公司创业初期哪个从国有银行贷到过钱?)

  • 相关阅读:
    编程题目: PAT 1012. 数字分类 (20)
    编程题目: PAT 1011. A+B和C (15)
    Poj3683(2-set
    LightOJ 1427(AC自动机
    UVA 11990(BIT套treap
    网络流汇总....
    10月——备战区域赛
    去掉ubuntu的文件管理器中“位置”栏里的无用标签
    Poj 2104(主席树入门
    Poj 1568(极大极小搜索
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3052232.html
Copyright © 2020-2023  润新知