数据结构期末考点复习

排序

快速排序

  • 选取pivot,左边放小的,右边放大的

    int Partition(SqList& L,int low, int high){
        L.r[0]=L.r[low];
        pivotkey=L.r[low].key;
        while(low<high){
            while(low<high&&L.r[high].key>=pivotkey) high--;
            L.r[low]=L.r[high];
            while(low<high&&L.r[low].key<=pivotkey) low++;
            L.r[high]=L.r[low];
        }
        L.r[low]=L.r[0];
        return low;
    }
    
    void QSort(Sqlist& L,int low,int high){
        if(low<high){
            pivotloc = Partition(L,low,high);
            QSort(L,low,pivotloc-1);
            QSort(L,pivotloc+1,high);
        }
    }
    

循环队列

  • 数据结构

    typedef struct{
        QElemType *base;
        int front,rear,tag;
    }SqQueue;
    
  • 初始化队列

    Status InitQueue(SqQueue &Q){
        Q.base = (Q.QElemtype*)malloce(sizof(QElemType)*MAXQSIZE);
        Q.front = Q.rear = 0;
        return OK;
    }
    
  • 入队

    bool EnQueue(SqQueue &Q, QElemType e){
        if(Q.tag==1&&Q.front==Q.rear) return ERROR;
        Q.base[rear] = e;
        Q.rear = (Q.rear +1) % MAXQSIZE;
        if(Q.tag==0) Q.tag=1;	//非满->满
        return OK;
    }
    
  • 出队

    bool DeQueue(SqQueue &Q, QElemType e){
        if(Q.tag==0&&Q.front==Q.rear) return ERROR;
        e = Q.base[Q.front];
        Q.front = (Q.front +1) % MAXQSIZE;
        if(Q.tag==1) Q.tag=0; //满->非满
        return OK;
    }
    

树和二叉树

树的数据结构

  1. 双亲表示法

    typedef struct PTNode{
    	TElemType data;
    	int parent;
    }PTNode;
    typedef struct{
    	PTNode nodes[MAX_TREE_SIZE];
     int r,n;		//根的位置和结点数
    }PTree;
    
  2. 孩子表示法

    typedef struct CTNode{
     	int child;
     struct CTNode *next;
    }*ChildPtr;
    typedef struct{
        TElemType data;
        ChildPtr firstchild;
    }CTBox;
    typedef struct{
     	CTBox nodes[MAX_TREE_SIZE];
    	int r,n;		//根的位置和结点数
    }CTree;
    
  3. 二叉链表示法

    typedef struct CSNode{
    	Elem data;
    	struct CSNode *firstchild, *nextsibling;
    } CSNode, *CSTree;
    
  • 求树的深度

      int TreeDepth(CSTree T){
         if(!T) return 0;
         else{
           	h1 = TreeDepth(T->firstchild);
           	h2 = TreeDepth(T->nextsibling);
            return (max(h1+1,h2));
         }
     }
    

二叉树

性质:

  • n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1
  • 完全二叉树深度 ⌊ l o g 2 n ⌋ + 1 \lfloor log_2{n}\rfloor+1 log2n+1

顺序存储结构

#define MAX_TREE_SIZE 100	//二叉树的最大结点数
typedef TEleType SqBiTree[MAX_TREE_SIZE];
SqBiTree bt;

链式存储结构

  • 二叉链表

    typedef struct BiTNode{	
    	TElemType data;
    	struct BiNode *lchild, *rchild
    }BiTNode, *BiTree;
    
  • 三叉链表

    typedef struct TriTNode { // 结点结构
    	TElemType data;
    	struct TriTNode *lchild, *rchild; // 左右孩子指针
    	struct TriTNode *parent; //双亲指针
    } TriTNode, *TriTree;
    
  • 双亲链表

    dataparentLRTag
    保存的数据双亲指针左右孩子标志域
    typedef struct BPTNode { // 结点结构
    	TElemType data;
    	int *parent; // 指向双亲的指针
    	char LRTag; // 左、右孩子标志域
    } BPTNode;
    
    typedef struct BPTree{ // 树结构
    	BPTNode nodes[MAX_TREE_SIZE];
    	int num_node;	 // 结点数目
    	int root; 		// 根结点的位置
    } BPTree;
    

二叉树遍历操作

  • 先序遍历

    • 递归算法

      Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e)){
            if(T){
                if(Visit(T->data))
                    if(PreOrderTraverse(T->lchild,Visit))
                        if(PreOrderTraverse(T->rchild,Visit)) return OK;
                return ERROR;
            }else return OK;
        }
      
    • 非递归算法

      Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e)){
          InitStack(S); Push(S,T);
          while(!StackEmpty(S)){
              Pop(S,p);if(!Visit(p->data)) return ERROR;
              Push(S,p->rchild);Push(S,p->lchild);//因为栈是后进先出,所以先入右孩子
          }
          return OK;
      }
      
  • 中序遍历

    • 递归算法

      Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e)){
          if(T){
              if(InOrderTraverse(T->lchild, Visit))
                  if(Visit(T->data))
                      if(InOrderTraverse(T->rchild, Visit)) return OK;
              return ERROR;
          }else return OK
      }
      
    • 非递归算法

      Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e)){
          InitStack(S); Push(S,T);
          while(!StackEmpty(S)){
              while(GetTop(S,p)&&p) Push(S,P->lchild);
              Pop(S,p);
             	if(!StackEmpty(S)){
                  Pop(S,p); if(!Visit(p->data)) return ERROR;
                  Push(S,p->rchild);
              }
          }
          return OK;
      }
      
  • 层次遍历

    Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType e)){
        InitQueue(Q);
        BiTree p;
        EnQueue(Q,T);
        while(!QueueEmpty(Q)){
            Dequeue(Q,p);
            Visit(p);
            if(p->lchild!=NULL) EnQueue(Q,p->lchild);
            if(p->rchild!=NULL) EnQueue(Q,p->rchild);
        }
    }
    
  • 求第k层上叶节点的数量

    int LevelOrderTraverse(BiTree T,int k){
    	InitQueue(Q);
     	BiTree p;
        EnQueue(Q,T);
        curWidth=0;depth=1;num=0;
    
        while(!QueueEmpty(Q)){   
            curWidth = QueueLenth(Q);
            for(v=0;v<curWidth;v++){
                Dequeue(Q,p);
                if(depth==k&&p->lchild==NULL&&p->rchild==NULL) num++;
                if(p->lchild!=NULL) EnQueue(Q,p->lchild);
           		if(p->rchild!=NULL) EnQueue(Q,p->rchild);
            }
            if(depth==k) break;
            else depth++;
        }
        return num;
    }
    

输出根到叶结点路径

void AllPath(Bitree T, Stack &S){
    if(T){
        Push(S,p->data);
        if(!T->lchild&&!T->rchild) PrintStack(S);//左右子树都是空(叶节点)
        else{
            AllPath(T->lchild);
            AllPath(T->rchild);	
        }
        Pop(S);
    }
}

求树的繁茂度(最大宽度*高度)

  • 求最大宽度

    int Width(BiTree T){
      InitQueue(Q);
      BiTree p;
    EnQueue(Q,T);
    	int maxWidth=0;
    	int curWidth=0;
    	while(!QueueEmpty(Q)){
        	curWidth = QueueLenth(Q);
        	if(curWidth>maxWidth) maxWidth=curWidth;
        	for(int i=0;i<curWidth;i++){
            	DeQueue(Q,p);
            	if(p->lchild!=NULL) EnQueue(Q,p->lchild);
        		if(p->rchild!=NULL) EnQueue(Q,p->rchild);
        	}
    	}
    }
    
  • 求树的高度

    int Height(BiTree T){
        if(T==NULL) return 0;
        int l = Height(T->lchild);
        int r = Height(T->rchild);
        return l>r?l+1;r+1;
    }
    

线索二叉树

  • 数据结构

    typedef enum PointerTag{Link, Thread} ;
    typedef struct BiThrNod{
        TElemType data;
        struct BiThrNode *lchild,*rchild;
        PointerTag LTag,Rtag;
    }BiThrNode,*BiThrTree;
    
  • 中序线索化(带头节点)

    void InThreading(BiThrTree p){
        if(p){
            InThreading(p->lchild);
            if(!p->lchild){
                p->LTag = Thread; p->lchild = pre;
            }
            if(!pre->rchild){
                pre->RTag = Thread; pre->rchild = p;
            }
            InThreading(p->rchild);
        }
    }
    Status InOrderThreading(BiThrTree &Thrt,BiThrTree T){
        if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrTree)))) exit(OVERFLOW);
        Thrt->LTag = Link; Thrt->RTag = Thread;
        Thrt->rchild = Thrt;
        if(!T) Thrt->lchild = Thrt;
        else{
            Thrt->lchild = T; pre = Thrt;
            InThreading(T);
            pre->rchild = Thrt; pre->RTag = Thread;
            Thrt->rchild = pre;
        }
        return OK;
    }
    
    
  • 中序遍历线索树(找到最左结点后一直往右走)(带头节点)

    Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e)){
        p = T->lchild;
        while(p!=T){
            while(p->LTag = Link) p = p->lchild;
            if(!Visit(p->data)) return ERROR;
            while(p->RTag = Thread&&p->rchild!=T){
                p = p->rchild; Visit(p->data);
            }
            p = p->rchild;
        }
    }
    

最小生成树

Prim算法

  • 寻找局部最优解
  • 每次将距离当前最小生成树最近的节点加入
  • 适合稠密图
  • 只与顶点数量相关
void MiniSpanTree_PRIM(MGraph G, VertexType u){
    k = LocateVex(G,u);
    for(j = 0;j<G.vexnum;++j)
        if(j!=k) closedge[j] = {u, G.arcs[k][j].adj};
    closedge[k].lowcost = 0;
    for(i = 1;i<G.vexnum;++i){
        k=minimum(closedge);
        printf(closedge[k].adjvex, G.vexs[k]);
        closedge[k].lowcost = 0;
        for(j=0;j<G.vexnum;++j)
            if(G.arcs[k][j].adj<closedge[j].lowcost)
                closedge[j] = {G.vexs[k], G.arcs[k][j].adj};
    }
}

无向图

深度优先搜索

  • 基础算法
void DFSTraverse(Graph G,Status(*Visit)(int v)){
	VisitFunc = Visit;
    for(v=0;v<G.vexnum;v++) visited[v]=FALSE;
    
    for(v=0;v<G.vexnum;v++){
        if(!visited[v]){
            visited[v]=TRUE;
            DFS(G,v);
        }
    }
}
void DFS(Graph G, int v){
    visited[v]=TRUE; VisitFunc(v);//访问结点
    
    for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)){
        if(!visited[w]) DFS(G,w);
    }
}
  • 非递归

    void DFS_Non_RC(AGraph& G, int v){
    	int w;
        InitStack(S);
        for(i=0;i<G.vexnum;i++){		//初始化标记数组
            visited[i]=False;
        }
        
        Push(S,v);
        visited[v]=True;
        
        while(!IsEmpty(S)){
    		k=Pop(s);
            visit(k);
            for(w=FirstNeighbor(G, k);w>=0;w=NextNeighbor(G,k,w)){
                if(!visited[w]){
    				Push(S,w);
                    visited[w]=True;
                }
            }
        }
    }
    
  • 查找路径 v → s v\to s vs

    void DFSearch(Graph G,int v,int s,char* PATH){
        visited[v]=TRUE;
        Append(Path,getVertex(v));
        for(w=FirstAdjVex(G,v);w>=0&&!found;w=NextAdjVex(G,v,w)){
            if(w==s){found = TRUE;Append(Path,w)}
            else if(!visited[w]) DFSearch(G,w,s,PATH);
        }
        if(!found) Delete(PATH);
    }
    
  • 判断是否有环

    • 0:未访问
    • 1:正在访问(在递归栈中)
    • 2 :已经访问
    int hasCycle(Graph* G) {
        for(v=0;v<G.vexnum;v++) visited[v]=FALSE;
        
        for(v = 0; v < G.vexnum; i++){
            if(!visited[v])
                if(DFS_hasCycle(G, v)) return 1;
        }
        return 0;
    }
    int DFS_hasCycle(Graph G, int v){
        if(visited[v]==2) return FALSE;
        visited[v] = 1;
        for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)){
            if(DFS_hasCycle(G,w)) return TRUE;
        }
        visited[v] = 2;
        return FALSE;
    }
    
  • 判断是否存在经过顶点 v v v的回路

    bool dfs(Graph G, int v, int parent){
        visited[v] = TRUE;
        Path[v] = TRUE;
        len++;
        for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)){
            if(!visited[w]){
                if(dfs(G,w,v)) return TRUE;
            }
            else if(len>=3&&Path[w]&&w!= parent){return TRUE} 
        }
        Path[v] = FALSE;
        return FALSE;
    }
    
    bool dfs(Graph G, int v, int s){
        visited[v]=TRUE;
        len++;
         for(w=FirstAdjVex(G,v);w>=0&&!found;w=NextAdjVex(G,v,w)){
           if(w==s&&len>=3) {found = TRUE; return TRUE;}
           else if(!visited[w]) dfs(G,w,s);
        }
        if(!found) return FALSE;
    }
    

广度优先搜索

  • 基础算法

    void BFSTraverse(Graph G,Status(*Visit)(int v)){
        for(v=0;v<G.vexnum;v++) visited[v]=FALSE;
        InitQueue(Q);
    
        for(v=0;v<G.vexnum;v++){
            visited[v]=TRUE; Visit(v);
            EnQueue(Q,v);
            while(!Empty(Q)){
                DeQueue(Q,u);
                for(w = FirstAdjvex(u);w>=0;w = NextAdjvex(G,v,w))
                    if(!visited[w]){
                        visited[w]=TRUE; Visit(w);
                        EnQueue(Q,u);
                    }
            }
        }
    }
    
  • 最短路径长度为k的节点

    void FindPath(Graph G,int v,int k){
        for(i=0;i<G.vexnum;i++) visited[i]=FALSE;
      	InitQueue(Q);
        distance[v] = 0; visited[v] = TRUE;
        EnQueue(Q,v);
        while(!Empty(Q)){
            DeQueue(Q,u);
            for(w = FirstAdjvex(G,v);w>=0;w = NextAdjvex(G,u,w)){
                if(!visited[w]){
                    visited[w] = TRUE;
                    distance[w] = distance[u] + 1;
                    EnQueue(Q,w);
                }
            }
        }
        for(i=0;i<G.vexnum;i++){
            if(distance[i]==k) printf(G.vertices[i]);
        }
    }
    

有向无环图及其应用

拓扑排序

  • 每次选取入读为0的点进行输出

    //邻接表储存
    Status TopologicalSort(ALGraph G){
        FindInDegree(G, indegree);//求各顶点的入度
        InitStack(S);	//初始化用于保存入度为0的栈
        for(int i;i<G.vexnum;i++)
        {
    		if(!indegree[i]) Push(S,i);   //栈中加入入度为0的点 
        }
        count = 0;//已经输出的顶点数量
        while(!StackEmpty(S))
        {
            Pop(S,i);
            printf(i,G.vertices[i].data);//输出
            ++count;
            
            for(p=G.vertices[i].firstarc;p;p=p->nexttarc)
            {
                k = p->adjvex;
                if(!(--indegree[k])) Push(S,k);
            }
        }
        if(count<G.vexnum) return ERROR;
        else return OK;
    }
    //不能进行拓扑排序则为有环
    
    

关键路径算法

  • ve(vertex-early)(顶点事件最早发生时间),更新取大:(前一个点+边)拓扑

  • vl(vertex-late)(顶点事件最晚发生时间),更新取小:(前一个点+边)逆拓扑

  • e(活动最早发生时间),即发出点的最早时间

  • l(活动最晚发生时间),即指向点的最晚 − - 边权

Status Toplogicalsort(ALGraph G,Stack &T){
    FindInDegree(G,indegree);
    InitStack(S);count=0;ve[0..G.vexnum-1]=0;
    while(!StackEmpty(S))
    {
        Pop(S,j);Push(T,j);++count;
        for(p=G.vertex[j].firstarc;p;p=p->nextarc)
        {
            k=p->adjvex;
            if(!(--indegree[k])) Push(S,k);
            if(ve[j]+*(p->weight)>ve[k]) ve[k]=ve[j]+*(p->weight);
        }
    }
    if(count<G.vexnum) return ERROR;
    else return OK;
}

void CriticalPath(ALGraph G)
{
    if(!Toplogical(G,T)) return ERROR;
    vl[0...G.vexnum-1]=ve[G.vexnum-1];
    while(!StackEmpty(S))
    {
		Pop(S,j);
        for(p=G.vertices[j];p;p=p->nextarc)
        {
            k = p->adjvex;dut = p->weight;
            if(vl[k]-dut<vl[j]) vl[j]=vl[k]-dut;
        }
        for(j=0;j<G.vexnum;j++)
        {
             for(p=G.vertices[j];p;p=p->nextarc)
             {
                 k = p->adjvex;det = p->weight;
                 ee = ve[j]; el=vl[k]-dut;
                 tag = ee==el?1:0;
                 printf(j,k,dut,ee,el,tag);
             }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值