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);
}
}