1、改造表头为T的双向链表,使其right域保持原来的位置关系,并且left域根据key值大小,从大到小排序
思路:
- 清空所有左指针
- 定义三个指针,p为当前的查找指针,q为当前的最小元素指针,tail为尾指针
- 不断找到最小元素,然后插入的当前的tail节点当中(尾插法,如果是从小到大就头插)
- 循环不断插入,直到所有节点都已经有左指针
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中,根据后序和中序序列,创建二叉树
整体思路:(找到根节点在中序的划分,然后根据划分,递归建立左右子树)
(可以找个例子更好找到下标之间的关系)
- 找到根节点,后序遍历为最后一个节点(先序为第一个节点)
- 找到根节点在中序的位置,然后计算左右子树长度
- 分别判断左右子树长度是否为空,不为空则建立左右子树
a)(1)左子树长度不为0,根据下标,找到在中序和后序左子树的位置,递归
(2)左子树长度为0,左子树为空
b)(1)右子树长度不为0,根据下标,找到在中序和后序右子树的位置,递归
(2)右子树长度为0,右子树为空 - 返回根节点
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;
}