**
栈
**
顺序栈:
base,top,top始终指向栈顶元素的下一个位置
入栈需要判断栈满
出栈需要判断栈空
入栈:
if(S.top-S.base==S.stacksize) return ERROR;
else *S.top++=e;
出栈:
if(S.top==S.base) return ERROR;
else e=*--S.top;
顺序栈初始化代码:
S.base=new int[MAXSiZE];
if(!S.base) return ERROR;//指针为空 if(!S.base)
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
链栈
栈只在栈顶进行插入和删除,所以将链表表头作为栈顶即可
一般链栈无头结点,头指针即指向栈顶元素。
链栈入栈时无需判断,出栈时需判空。
所以链栈的入栈和出栈即为在表头进行插入和删除节点。
链栈为空:
S=NULL;
**
递归的简单应用
**
单链表逆序打印
void name(L)
{
L=L.next;
if(L!+NULL)
{
name(L)
print L;
}
}
单链表中的最大整数
int maxlist(pp)
{
int t1,t2,max;
t1=pp.data;
pp=pp.next;
if(pp==NULL) return -20;
else
{
t2=pp.data;
max=t1>t2?t1:t2 //大于号。问号,冒号构成求最大值式子
return max;
}
单链表逆置
Linklist nizhi(pp)
{
if(pp.next==NULL)
return pp;
else
{
Linklist pp=nizhi(pp.next);
pp.next.next=pp;
return temp;
}
}
逆序打印字符串
void print(char *p)
{
if(*p!='\0') //与逆序打印单链表区别在此处
{
print(p+1);
printf("%c",*p);
}
}
**
队列
**
循环队列
和顺序栈相同,尾指针rear始终指向队尾的下一个位置
出队入队要判空:rear=front 判满:(rear+1)%MAXSIZE==front;
求队列长度:(rear-front+maxsize)%maxsize;
循环队列存储结构:
typedef struct
{
int *base;
int front;
int rear;
}
链队
链队 一般有头结点。头指针始终指向头结点!
入队:在表尾加结点,出队:在表头去结点;
所以在出队时,是front.next在变化而非front;
链队判空:Q.rear=Q.front(都指向头结点);
值得注意的是链队的出队,当出队结点是最后一个结点时,要把rear复位到头结点;
链队存储结构
结点结构体
+
typedef struct
{
Ptr front;
Ptr rear;
}
链队初始化
Status InitQueue(Q)
{
Q.rear=Q.front=new Qnode;
Q.front.next=NULL;//!!
return OK;
}
链队出队
Status Dequeue(Q,e)
{
if(Q.front==Q.rear) return ERROR;
Ptr p=Q.front.next;
e=p.data;
Q.front.next=p.next;
if(p==Q.rear) Q.rear=Q.front;
delete p;
return OK;
}
**
二叉树
二叉树的层序遍历:
需要一个队列来存储树的节点,如果树不为空,先入队根节点,然后循环执行以下操作:1.出队2.访问除对接点3.将该节点的左右孩子入队
层序遍历
Status LevelOrderTraverse(BinTNode *T)
{
LinkQueue *p=(LinkQueue *)malloc(sizeof(LinkQueue));
InitQueue(p);
if(T!=NULL)
EnQueue(p,*T);
BinTNode temp;
while(IsQueueEmpty(p)==0)
{
DeQueue(p,temp);
printf("%3c",temp.data);
if(temp.lchild!=NULL) EnQueue(p,*temp.lchild);
if(temp.rchild!=NULL) EnQueue(p,*temp.rchild);
}
printf("\n");
return OK;
}
图
**邻接矩阵存储结构:**一个一维数组存储顶点信息,一个二维数组存储边信息,还可以有个vexnum,arcnum。
在创建图时,二维数组要先用一个二重循环赋0或无穷大。再设可走边。
深度优先遍历(邻接矩阵存储结构):
递归思路:从某个顶点出发深度优先遍历一个图分为以下几部分工作:
1.访问该顶点 2.对该顶点的各个邻接点再进行深度优先遍历
void DFSTraverse(MGraph G,int v)
{
printf("%c ",G.vexs[v]);
visit[v]=1;
for(int i=0;i<G.numVertexes;i++)
{
if(G.arc[v][i]&&!visit[i]) DFSTraverse(G,i);
}
}
广度优先遍历(邻接矩阵存储结构):
思路:需要一个队列,与树的层序遍历不同处:
从某顶点开始的广度优先遍历,先访问该顶点,在入队
之后循环以下操作:
1.将队头顶点出队 2.将该顶点的所有邻接顶点访问并入队
不同之处还有:树入队的是顶点数据类型,图入队的是int类型的顶点序号。
void BFSTraverse(MGraph G,int v)
{
int e;
Queue Q;
InitQueue(&Q);
printf("%c ",G.vexs[v]);
EnQueue(&Q,v);
vis[v]=1;
while(!QueueEmpty(Q))
{
DeQueue(&Q,&e);
for(int i=0;i<G.numVertexes;i++)
{
if(G.arc[e][i]&&!vis[i])
{
printf("%c ",G.vexs[i]);
vis[i]=1;
EnQueue(&Q,i);
}
}
}
}
查找和二叉排序树
折半查找
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]===key) return mid;
else if(a[mid]>key) high=mid-1;
else low=mid+1;
}
二叉排序树的查找
int find(Tree* T,int e)
{
if T==NULL return 0;
else if(T.data==e) return 1;
else if(T.data<e) return find(T.rlchld,e);
else return find(T.lchild,e);
}
二叉排序树的判定
int panding(Tree* T)
{
if(T==NULL) return 1;
else if(!T.lchild&&1T.rchild) return 1;
else if(!t.child&&T.rchild) return (T.rchild.data>T.data)&&panding(T.rchild);
else if(t->lchild==NULL&&t->rchild!=NULL) return ((t->rchild->data>t->data)&&IsSearchTree(t->rchild));
else if(t->lchild&&t->rchild) return (((t->lchild->data<t->data)&&(t->data<t->rchild->data))&&IsSearchTree(t->lchild)&&IsSearchTree(t->rchild));