19 计学

1、改造表头为T的双向链表,使其right域保持原来的位置关系,并且left域根据key值大小,从大到小排序

思路:

  1. 清空所有左指针
  2. 定义三个指针,p为当前的查找指针,q为当前的最小元素指针,tail为尾指针
  3. 不断找到最小元素,然后插入的当前的tail节点当中(尾插法,如果是从小到大就头插)
  4. 循环不断插入,直到所有节点都已经有左指针
typedef struct DNode{
	int data;
	struct DNode *prior, *next;
}*Dlist; 

int LevelUp(DNode *head){
	int min;
	DNode *p, *q, *tail;			//p为查找指针,q为定位指针,tail为左链域的尾指针
	p = head->next; q = NULL; tail = head; 	//初始化
	
	while(p != head){			//清空所有左指针 
		p->prior = NULL;
		p = p->next; 
	} 
	
	while(true){		
		p = head->next;			//每次从新找最小元素
		min = MAX;
		
		while(p != NULL){
			if(p->prior != NULL) p = p->next;		//当前节点左指针已经为空说明已经排好序
			
			else if(p->data < min){					//如果比当前最小值小,则交换位置 
				q = p;
				min = p->data;
				p = p->next;
			} 	
			else
				p = p->next;						//不是,继续往下找 
		}
		if(min == MAX)
			return 1;								//min没变,说明所有节点排好序了
		q->prior = tail;
		tail = q; 
	}
}

2、二叉树的后序遍历序列存放在数组A中,中序遍历序列存放在数组B中,根据后序和中序序列,创建二叉树

整体思路:(找到根节点在中序的划分,然后根据划分,递归建立左右子树)
(可以找个例子更好找到下标之间的关系)

  1. 找到根节点,后序遍历为最后一个节点(先序为第一个节点)
  2. 找到根节点在中序的位置,然后计算左右子树长度
  3. 分别判断左右子树长度是否为空,不为空则建立左右子树
    a)(1)左子树长度不为0,根据下标,找到在中序和后序左子树的位置,递归
    (2)左子树长度为0,左子树为空
    b)(1)右子树长度不为0,根据下标,找到在中序和后序右子树的位置,递归
    (2)右子树长度为0,右子树为空
  4. 返回根节点
typedef struct TNode{
	int data;
	struct TNode *left, *right;
}*Tree; 

Tree PostInCreate(int A[], int B[], int l1, int f1, int l2, int f2){
	TNode *root = (TNode *)malloc(sizeof(TNode));
	root->data = A[f1];
	int i = 0;
	for(i = 0; B[i] != root->data; i++);		//找到根节点在中序遍历的划分
	int llen = i - l2;							//左子树长度 
	int rlen = f2 - i; 							//右子树长度
	
	if(llen){									//递归建立左子树 
		root->left = PostInCreate(A, B, l1,l1+llen-1, l2, l2+llen-1);
	}
	else{										//左子树为空 
		root->left = NULL;
	}
	if(rlen){									//递归建立右子树 
		root->right = PostInCreate(A, B,f1-rlen, f1-1,f2-rlen+1, f2);
	} 
	else{										//右子树为空 
		root->right = NULL;
	}
	return root;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值