1.头插法
void CreateListHead(Linklist *L,int n)
{
Linklist p; //创建表指针p,用于插入数据
int i;
srand(time(0));
*L=(Linklist)malloc(sizeof(Node)); //表头分配空间
(*L)->next=NULL;
for(i=0;i<n;i++)
{
p=(Linklist)malloc(sizeod(Node)); //表指针p分配空间
p->data=rand()%100+1; //存入该随机数
p->next=(*L)->next; //将p的下一个结点赋为表L的下一结点,第一次为NULL,第二次为p1,第二次为p2......依此类推
(*L)->next=p; //表L下一结点指向p所指结点数据
}
}
//尾插法: for循环下改变后两行思想
{
r=*L;
(*L)->next=p;
r=p;
}
......还有不借助p实现头插法尾插法等等。
2.二叉树的遍历
(1)前序
递归:void PreOrderTraverse(BiTree T)
{
if(T==NULL)
return;
printf("%c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
非递归:void PreOrder(BiTree T)
{
Stack s;
InitStack(s);
BiTree p=T;
while(p!=NULL||!StackEmpty(s))
{
if(p!=NULL) //结点p不为空
{
push(s,p); //压p进s
visit(p); //实际应用中,将访问函数换成自己的功能函数,实现
p=p->lchild;
}
else
{
pop(s,p);
p=p->rchild;
}
}
}
(2)中序
递归:void InOrderTraverse(BiTree T)
{
if(T==NULL)
return;
InOrderTraverse(T->lchild);
printf("%c",T->data); //visit()
InOrderTraverse(T->rchild);
}
非递归:跟前序类似,只不过visit()的位置不一样
具体说说后序遍历
(3)后序:后序遍历递归就不写了,非递归的话跟前面有些不一样,顺序是访问最左子树,在访问右子树的最左子树(如果存在的话),否则就是访问右子树,然后访问父母----依此类推,具体如下:
void PostOrder(BitTree T)
{
Stack s;
InitStack(s);
BiTree p=T,r=NULL; //r为访问完的尾标志,防止二次访问
while(p||!StackEmpty(s))
{
if(p)
{
push(s,p);
p=p->lchild; //走到最左
}
else //当没有左子树了
{
GetTop(s,p); //判断该结点右子树是否存在,并且该右子树不能被访问过
if(p->rchild&&p->rchild!=r)
{
p=p->rchild; //存在,即访问右子树
push(s,p); //再压栈,依次访问左子树
p=p->lchild;
}
else
{
pop(s,p); //上述情况皆ok了之后,压该结点入栈,访问
visit(p);
r=p; //置尾,防止二次访问
p=NULL;
}
}
}
}
(4)层次遍历:层次遍历要用到队列
void LevelOrder(BiTree T)
{
InitQueue(Q); //初始化队列
BiTree p;
p=T; //指向
EnQueue(Q,T);
while(!IsEmpty(Q)) //队列不满
{
DeQueue(Q,p); //出队列
visit(p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}