目录
一.二叉树的顺序存储
1.规则
2.二叉树的遍历
2.1中序遍历
2.由顺序结构构建链式二叉树
3.由链式创建顺序二叉树。
4.由链式二叉树构建中序双链表
二.堆排序与优先级队列
1.最小堆的调整过程
2.优先级队列(堆排序实现)
思想:跟链式存储的遍历方式一样,左右跟
void InOrder(ElemType*ar,int i,int n)
{
if(i
非递归的方式:跟链式的方法类似,借用一个栈 ,二叉树的根节点入栈,左子树依次入栈,如果左子树为空,出栈顶元素,打印栈顶元素,一个右子树入栈,循环上述过程。终止条件,栈为空或者i >= n(下标超过结点个数,越界)。
void NiceOrder(ElemType *ar,int n)//n为结点个数
{
if(NULL == ar || n < 1) return;
stack st;
int i = 0;
while(!st.empty() || i < n)
{
while(i < n && ar[i]!=END)//i
思想:利用中序遍历的方式将顺序结构中的结点赋值给链式二叉树
struct BtNode *Create(ElemType *br,int i,int n)
{
struct BtNode *s = NULL;
if(br[i]!=END && i < n)
{
s = Buynode();
s->data = br[i];
s->leftchild = Create(br,2*i+1,n);
s->rightchild = Create(br,2*i+2,n);
}
return s;
}
struct BtNode *CreateAr(ElemType *br,int n)
{
struct BtNode *s = NULL;
if(br != NULL && n>0)
{
s = Create(br,0,n);
}
return s;
}
void LinkArray(struct BtNode* ptr,ElemType *br,int i) //将ptr对应的数值放到数组中
{
if(ptr!=NULL)
{
br[i] = ptr->data;
LinkArray(ptr->leftchild,br,i*2+1);
LinkArray(ptr->rightchild,br,i*2+2);
}
}
int main()
{
int ar[] = {31,23,12,66,-1,5,17,70,62,-1,-1,-1,88,-1,55};
int br[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int n = sizeof(ar)/sizeof(ar[0]);
InOrder_Ar(ar,n);//中序遍历
cout<
最小堆的特点,每个根结点都小于它的左孩子和右孩子。
最大堆特点:每个根节点都大于它的左孩子和右孩子。
步骤(1)最后一个结点的下标j为7,它的根节点i下标为(j-1)/2 = 3,将i结点的值取出来,j没有右孩子,i < j 将i放到原位置。
i - 1等于2,将i结点的值取出来给tmp,j = 5,j比右孩子小,再将tmp的值与 j结点的值比较,j结点的值更小,将j 结点的值给i结点。i = j = 5,j = 11,超出数组的最大下标,退出,i结点的值 = tmp。
i - 1 = 1,j = 2* i + 1 = 3,tmp = i结点的值为17,j结点的值比它的右孩子结点的值小,j结点的值与tmp 比较,j更小,j结点的值给i结点,i = j = 3, j = 7, j结点的值大于tmp退出,i结点的值 = tmp。
得到下图所示的结果:
i - 1 = 0,现在开始从0结点开始调整。
步骤(2)从0开始调整
i = 0,tmp = 0结点的值=53, j = i*2+1 = 1,j->data < tmp ,i->data = j->data。
i = j = 1, j = 3,j->data = 17,17 i = j = 3,j = 7,j->data = 23,23 i = j = 7,j = 15,越界,退出 i结点的值为tmp(53) 最终结果如下图所示: 将ar数组排序后如下图所示: 1.在堆中插入元素的过程: 插入的元素在数组的最后一个位置,然后进行调整。下面用具体的例子来说明。 如在上面的图中插入5. 5的下标为8 , j = 8, i = (8-1)/2 = 3, tmp = ar[8], ar[3] > tmp,所以ar[8] = ar[3] = 9. j = i = 3, i = (j-1)/2 = 1, 17 > 5,所以将17放到ar[j]的位置 依次类推,直到 j = 0,tmp的值给ar[0]结束。 2.删除堆顶的元素 将最后一个元素赋给堆顶,然后用从上向下调整堆的函数 3.优先级队列代码实现 每次取堆顶(最小数)代码截图: void FilterDown(int *ar,int begin,int end)//从上向下调整
{
int i = begin,j = 2*i+1;//leftchild
int tmp = ar[i];
while(j <= end)//
{
if(j < end && ar[j] > ar[j+1])//ar[j+1]为右子树,j < end,j+1才不会超出范围
++j;
if(ar[j] < tmp)
{
ar[i] = ar[j];
}
else
{
break;
}
i = j;
j = i * 2 + 1;
}
ar[i] = tmp;
}
void HeapSort(int *ar,int n)
{
if(NULL == ar || n < 2) return;
int end = n-1;//最后一个元素的下标
int pos = (end - 1)/2;//第一个分支的根节点
while(pos >= 0)//建堆
{
FilterDown(ar,pos,end);
--pos;
}
while(end > 0)//将数组ar从大到小排序,将ar[0]与ar[end]交换,然后在将ar[0]-ar[end-1]按照最小堆排序
{
swap(ar[0],ar[end]);
end = end - 1;
FilterDown(ar,0,end);
}
}
int main()
{
int ar[] = {53,17,78,9,45,65,87,23};
int n = sizeof(ar)/sizeof(ar[0]);
HeapSort(ar,n);
return 0;
}
2.优先级队列(堆排序实现)
const int MAXSIZE = 100;
const int INCSIZE = 2;//增量为2
template