1.试设计一个算法,改造一个带表头结点的双向链表,所有结点的原有次序保持在各个结点的右链域rLink中,并利用左链域ILink把所有结点按照其值从大到小的顺序连接起来
思路:类似尾插法。先把所有结点的前驱指针全部断掉,然后根据后继指针遍历整个链表,每一轮找到一个最小的结点,然后把这个结点的前驱指针指向左链域的尾指针。最后所有结点的前驱指针都已连接,算法结束。因为左链域的指向是从右到左,所以从大到小链接的话,最小值的前驱应该是头结点。
#define Min 1000
typedef struct node
{
int data;
struct node *next;
struct node *prior;
}DRLNode;
int LevelUp(DRLNode* head)
{
int min; //记录未被左链域连接的结点中的最小值
DRLNode* p, * q, * tail; //p为查找指针 q为定位指针 tail为左链域的尾指针
p = head->next; q = NULL;
tail = head; //初始化
while (p != NULL)
{
p->prior = NULL;
p = p->next;
} //先将所有除头结点的结点的左指针清空
while (true) //将结点左链域从大到小排列
{
min = INF; //初始化 min定义为一个很大的数
p = head->next;
while (p != NULL)
{
if (p->prior != NULL) //如果p左指针不为空 说明已经在左链域中 不参与比较 直接向后移动
p = p->next;
else if (p->data < min) //判断结点是否为最小值结点
{
min = p->data;
q = p; //记录最小值结点
p = p->next;
}
else //不是最小值向后移动
p = p->next;
}
if (min == INF) //如果e的值没有变化说明结点都连接在左链域
return 1;
q->prior = tail;
tail = q; //这为关键连接代码,将该结点连接到左链域
}
}
2.二叉树的后序遍历序列存放在数组A中,中序遍历序列存放在数组B中,根据后序和中序序列,创建二叉树。
思路:根据后序,确立根节点,然后根据中序划分出左右子树,然后在左右子树中重复。
typedef struct node
{
int data;
struct node *lchild,*rchild;
}*Tree,Node;
Tree PostInCreat(int a[],int b[],int f1,int l1,int f2,int l2)
{
//f1,l1为后序的第一个和最后一个结点下标。f2,l2为中序的第一和最后一个结点下标
Tree root;
root=(Node *)malloc(sizeof(Node));
root->data=a[l1]; //根结点
int i;
for(i=f2;b[i]!=root->data;i++);//根结点在中序序列中的划分
int llen=i-f2; //左子树长度
int rlen=l2-i; //右子树长度
if(llen) //递归建立左子树
root->lchild=PostInCreat(a,b,f1,f1+llen-1,f2,f2+llen-1);
else //左子树为空
root->lchild=NULL;
if(rlen) //递归建立右子树
root->rchild=PostInCreat(a,b,l1-rlen,l1-1,l2-rlen+1,l2);
else //右子树为空
root->rchild=NULL;
return root;
}