zoukankan      html  css  js  c++  java
  • 数据结构基础

    //==========================================
    // 2-链表的操作
    //==========================================

    typedef int ElemType;
    typedef struct LNode{
        struct LNode* next;
        ElemType data;
    }LNode,*LinkList;
    
    //==2.1链表的插入
    Stauts InsertList(LinkList&L,int i,ElemType e)
    {
        LNode* p,*s;
        int j=0;
        p = L;
        while(p!=NULL&&j<i-1)
        {
            p=p->next;
            j++;
        }
        if(p==NULL||j>i-1) return ERROR;
        else
        {
            s = (LNode*)malloc(sizeof(LNode));
            s.data = e;
            s->next = p->next;
            p->next = s;
        }
        return OK;
    }
    //==2.2链表的删除
    Status ListDelete(LinkList&L,int i,Elemtype& e)
    {
        LNode*p,*s;
        p = L;
        int j=0;
        while(p!=NULL&&j<i-1)
        {
            p = p->next;
            j = j+1;
        }
        if(p==NULL||j>i-1)
        {
            return ERROR;
        }
        else
        {
            s = p->next;
            e = s->data;
            p->next = s->next;
            free(s);
            return OK;
        }
    
    }
    //==2.3带头结点的空链表
    void initLinkList(LinkList& L)
    {
        L = (LNode*)malloc(sizeof(LNode));
        L->next = NULL;
    }
    //==2.4前插法建立链表
    void createListFront(LinkList&L,Elemtype e)
    {
        LNode *s;
        s = (LNode*)malloc(sizeof(LNode));
        s->data = e;
        s->next = L->next;
        L->next = s; 
    }
    //==2.5后插法建立链表
    void createListRear(LinkList&L,Elemtype e)
    {
        LNode *s,*p=L;
        s = (LNode*)malloc(sizeof(LNode));
        s->data = e;
        while(p->next!=NULL)
        {
            p = p->next;
        }
        p->next = s;
        s->next = NULL;
    }
    //==2.6两个循环链表(带头节点)合并
    LinkList ListCombine(LinkList& L1,LinkList& L2)
    {
        LNode* p = L1;
        while(p->next!=L1) p = p->next;
        p->next = L2->next;
        p = L2;
        while(p->next!=L2) p = p->next;
        p->next = L1;
        return L1;
    }
    //==2.7单链表(不带头结点)的倒置
    void ListReverse(LinkList& L)
    {
        LNOde* p=L,*NewL=L;
        while(L!=NULL)
        {
            p=L;
            L = L->next;
            p->next = NewL->next;//头插法
            NewL->next = p;
        }
        L = NewL;
    }

    //==========================================
    // 3-堆栈队列
    //==========================================

    typedef int ElemType;
    #define STACK_SIZE 100
    #define STACK_INC_SIZE 10
    
    //========================3.1顺序栈
    //==3.1.1顺序栈的定义
    typedef struct Stack
    {
        ElemType* Base;
        ElemType* Top;
        int StackSize;
    }Stack; 
    //==3.1.2顺序栈的初始化
    Status initStack(Stack& S)
    {
        S.base = (ElemType*)malloc(size(ElemType)*STACK_SIZE);
        if(S.base == NULL)
        {
            return ERROR;
        } 
        else
        {
            S.StackSize = STACK_SIZE;
            S.top = S.base;
            return OK;
        }
    }
    
    //==3.1.3入栈
    Status push(Stack& S,ElemType e)
    {
        if(!StackFull(S))       //S.top-S.base>=S.StackSize
        {
            *(S.top++) = e;
            return OK;
        }
        else 
        {
            return ERROR;
        }
    }
    //==3.1.4出栈
    Status pop(Stack& S,ElemType& e)
    {
        if(!StackEmpty(S))  //S.top==S.base
        {
            e=*(--S.top);
            return OK;
        }
        else
        {
            return ERROR;
        }
    }
    //========================3.2链式栈
    //==3.2.1链式栈的定义
    typedef struct StackNode
    {
        StackNode* next;
        ElemType   data;
    }StackNode;
    typedef struct Stack
    {
        StackNode *top;
    }Stack;
    //==3.2.2出栈
    Status Pop(Stack& S,ElemType& e)
    {
        if(!StackEmpty(S))        //S.top ==NULL
        {
            StackNode* PNode;
            e = (S.top)->data;
            PNode = S.top;
            S.top = S.top->next;
            free(PNode);
            return OK;
        }
        return ERROR;
    }
    //==3.2.3入栈
    void Push(Stack& S,ElemType e)
    {
    
            StackNode* PNode;
            Pnode=StackNode*(malloc(sizeof(StackNode)));
            Pnode->data = e;
    
            Pnode->next = S.top; //前插法
            S.top = Pnode;
            return OK;
    }
    //========================3.3队列
    //==3.3.1链队的定义
    typedef struct QNode
    {
        ElemType data;
        struct QNode* next;
    }QNode;
    typedef struct Queue
    {
        QNode* front;
        QNode* rear;
    }QUEUE;
    //==3.3.2入队列
    void EnQueue(Queue& Q,ElemType e)
    {
        QueueNode* QNodePtr;
        QNodePtr=(QueueNode*)malloc(sizeof(QueueNode));
        QNodePtr->data = e;
        if(QueueEmpty(Q))
        {
            Q.rear = Q.front = QNodePtr;
        }
        else
        {
            Q.rear->next = QNodePtr;
            Q.rear = QNodePtr;
        }
    }
    //==3.3.2出队列
    Status DeQueue(Queue& Q,ElemType& e)
    {
        if(EmptyQueue(Q)) //Q.front ==NULL
        {
            return ERROR;
        }
        else
        {
            QueueNode* p = Q.front;
            Q.front = Q.front->next;
            e = p->data;
            free(p);
            return OK;
        }
    }
    //==3.3.4循环队列定义
    typedef struct CyclQueue
    {
        ElemType* data;
        int front;
        int rear;
    };
    #define QUEUE_MAX_SIZE 100
    //==3.3.5循环队列 出队列
    Status DeQueue(Queue Q,ElemType& e)
    {
        if(QueueEmpty(Q)) //Q.front==Q.rear
        {
            return ERROR;
        }
        else
        {
            e = Q.data[Q.front];
            Q.front = (Q.front+1)%QUEUE_MAX_SIZE;
            return OK;
        }
    }
    
    //==3.3.6循环队列 入队列
    Status EnQueue(Queue Q,ElemType e)
    {
        if(QueueFull(Q)) //(rear+1)%QUEUE_MAX_SIZE==front
        {
            return ERROR;
        }
        else
        {
            Q.data[Q.rear] = e;
            Q.rear = (Q.rear+1)%QUEUE_MAX_SIZE;
            return OK;
        }
    }

    //==========================================
    // 4.二叉树的操作
    //==========================================

    //==4.1二叉链表
    
    typedef char ElemType;
    typedef struct BiNode
    {
        struct BiNode* lchild;
        struct BiNode* rchild;
        ElemType data;
    }BiNode,*BiTree;
    //==4.1.1先序遍历
    void PreOrder(BiTree B,void(*visit)(ElemType& e))
    {
        if(T)
        {
            visit(B->data);
            PreOrder(B->lchild,visit);
            PreOrder(B->rchild,visit);
        }
    }
    //==4.1.2中序遍历
    void InOrder(BiTree B,void(*visit)(ElemType& e))
    {
        if(T)
        {
            InOrder(B->lchild,visit);
            visit(B->data);
            InOrder(B->rchild,visit);
        }
    }
    //4.1.3求二叉树的深度
    int BiTreeDepth(Bitree B)
    {
        int lDepth=0,rDepth=0,Depth=0;
        if(B)
        {
            lDepth = BiTreeDepth(B->lchild);
            rDepth = BiTreeDepth(B->right);
            Depth = 1+(lDepth>rDepth?lDepth:rDepth);
        }
        else 
        {
            Depth = 0;
        }
        return Depth;
    }
    //4.1.4求二叉树的结点数
    int BiTreeNodeCount(Bitree B)
    {
        int lNode=0,rNode=0,Node=0;
        if(B)
        {
            lNode = BiTreeNodeCount(B->lchild);
            rNode = BiTreeNodeCount(B->rchild);
            Node = lNode+rNode+1;
        }
        else
        {
            Node = 0;
        }
        return Node;
    }
    //4.1.5求二叉树的叶子节点数
    int BiTreeLeafCount(Bitree B)
    {
        int lLeaf=0,rLeaf=0,Leaf=0;
        if(T)
        {
            lLeaf = BiTreeLeafCount(B->lchild);
            rLeaf = BiTreeLeafCount(B->rchild);
            Leaf = lLeaf + rLeaf;
            if(Leaf==0) Leaf = 1;
        }
        else
        {
            Leaf = 0;
        }
        return Leaf;
    }
    //4.1.6二叉树的层次遍历
    void LayertOrder(Bitree& B)
    {
        BiNode* p;
        InitQueue(Q);
        EnQueue(B);
        while(EmptyQueue(B))
        {
            DeQueue(Q,p);
            //visit node p here 
            if(p->lchild) EnQueue(p->lchild);
            if(p->rchild) EnQueue(p->rchild);
        }
    }
    //4.1.6删除二叉树
    void DelBiTree(Bitree& B)
    {
        if(B->lchild) DelBiTree(B->lchild);
        if(B->rchild) DelBiTree(B->rchild);
        free(B);
    }
    //4.2.1双亲表示法
    #define M 100
    typedef struct node
    {
        int parent;
        ElemType data;
    }PT;
    PT tree[M];
    
    //4.2.2孩子链表表示法(数组加链表存储)
    typedef struct ListChild
    {
        int ChildIndex;// 数组中孩子结点在线性表存储中的索引
        struct ListChild* next;
    }ListChild;
    
    typedef struct ListChildTree
    {
        ElemType data;
        ListChild* FirstChild;
    }ListChildTree;
    ListChildTree tree[M];
    
    //4.2.3长子兄弟表示法
    //各种树转换为二叉树的表示方法
    typedef struct ChildSiblingNode
    {
        struct* ChildSiblingNode firstChild;
        struct* ChildSiblingNode NextSibling;
        ElemType data;
    }ChildSiblingNode;

    //==========================================
    // 5.图
    //==========================================

    //==5.1邻接矩阵的定义
    typedef char VertexType;
    typedef int EdgeType;
    #define MAXVEX 100
    typedef struct {
        VertexType Vertex[MAXVEX];
        EdgeType   Arc[MAXVEX][MAXVEX];
        int NumVertexs;
        int NumEdges;
    }MGraph;
    
    //==5.2邻接链表,与二叉树中孩子链表表示法类似
    typedef struct ListEdge//链表中的类型
    {
        struct ListEdge* next;
        int Adjvex;
    }ListEdge;
    
    typedef struct AdjNode//数组中的类型
    {
        ListEdge* FirstAdj;
        VertxType data;
    }AdjNode;
    
    typedef struct AdjList
    {
        AdjNode adjList[MAXVEX];
        int NumVertexs;
        int NumEdges;
    }AdjList;

    图的遍历:
    1.深度优先遍历(类似于二叉树的前序遍历,纵向遍历)DFS
    2.广度优先遍历(类似于二叉树的层序遍历,横向遍历)BFS

    3.最小生成树
    prim和kruskal算法

    prim算法:选小,扩张,不要构成回环,稠密图适用,O(n^2)
    prim算法

    kruskal 算法:选小,避圈,稀疏图适用,O(nedge*log(nedge))
    kruskal 算法

    4.最短路径
    a.迪杰斯拉特算法(单源点最短路径)
    迪杰斯拉特算法
    b.弗洛伊德算法(所有节点间的最短路径)

    5.拓扑排序

     a.在有向图中选择一个没有前驱的顶点(入度为0),并输出
     b.删除该顶点和从它出发的弧线
     c.重复以上步骤,直到全部顶点输出或图中不存在入度为0的顶点(图中有有向环)
    

    6.关键路径

    //==========================================
    // 6.查找
    //==========================================

    //==6.1折半查找(迭代法)
    int BinarySearch(ElemType V[],int length,,ElemType Value)
    {
        int left = 0,right = length -1,mid;
        while(left<=right)
        {
            mid = (left+right)/2;
            if(V[mid]==Value)
            {
                return mid;
            }
            else if(V[mid]>Value)
            {
                right = mid -1;
            }
            else
            {
                left = mid + 1;
            }
        }
        rerurn -1;//未找到
    }
    //==6.2折半查找(递归法)
    int BinarySearch(ElemType V[],int low,int high,int kValue)
    {
        if(low>high) return -1;
        else
        {
            int mid = (low+high)/2;
            if(V[mid]==KValue)
            {
                return mid;
            }
            else if(V[mid]>KValue)
            {
                high = mid -1;
            }
            else 
            {
                low = mid +1;
            }
            BinarySearch(V,low,high,KValue);
        }
    }
    //==6.3二叉排序树(二叉查找树)
    //f的作用是当找不到kValue时,方便插入节点
    Stauts BiTreeSearch(BiTree B,ElemType KValue,BiNode f,BiTree &p)
    {
        if(!B)       //没找到关键字KValue
        {
             p = f;
             return FALSE;
        }
        else if(KValue == B->data)
        {
            p = B;
            return TRUE;
        }
        else if(KValue >B->data)
        {
            return BiTreeSearch(B->rChild,KValue,B,p);
        }
        else
        {
            return BiTreeSearch(B->lChild,KValue,B,p);
        }
    }
    //==6.4二叉排序树(动态插入)
    Status InsertBinarySearchTre(BiTree& B,int KValue)
    {
        BiNode* p,s;
        if(!BiTreeSearch(B,KValue,NULL,p))//未找到
        {
            s = (BiNode*)malloc(sizeof(BiNode));
            s->data = KValue;
            s->lChild = s->rChild = NULL;
    
            if(p==NULL) T = s;
            else if(p->data>KValue)
            {
                p->rChild = s;
            }
            else
            {
                p->lChild = s;
            }
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }

    6.5二叉排序树(查找并动态删除)
    //(独)子承父业;双子争位,前驱代之

    6.6平衡二叉树(AVL树)
    //左右子树都为AVL树,两子树高度差的绝对值不超过1的二叉排序树
    //查找,插入,删除的复杂度为log(n)

    6.7哈希表(基于计算的查找)
    将关键字进行一个运算,结果为它的地址
    常见方法:

    直接定址法
    数字分析法
    平方取中法
    折叠法
    除留余数法
    随机数法
    

    冲突处理:由于不同的关键字,经过运算可能是同一个地址(取决于哈希函数的选取)

    1.开放定址法

    2.链地址法
    这里写图片描述

    3.再哈希法

    //==========================================
    // 7.排序
    //==========================================

    //==7.1选择排序
    void Selectsort(SortType V[], int length)
    {
        int i, j = 0;
        for (int i = 0; i < length; i++)
        {
            //==未排序的部分的最小值
            int min_index=i;
            for (j = i+1; j < length; j++)
            {
                if (V[min_index]>V[j])
                {
                    min_index = j;
                }
            }
            if (V[i] != V[min_index]) 
            Swap(V[i], V[min_index]);//将最小值,加入到已排序的下一个
        }
    }
    //========================插入类排序
    //====7.2希尔排序
    /*
    直接插入算法的改进版,对于n比较大时有优势
    */
    void ShellSort(SortType V[], int length)
    {
        int gap = length / 2;
        while (gap!=0)
        {
            for (int i = gap; i < length; i++)
            {
                if (V[i] < V[i -gap])
                {
                    int j;
                    SortType temp = V[i];//index i表示待排序的index
                    for (j = i - gap; j>=0; j = j - gap)//插入已有顺序的部分,从最后一个有序元素开始
                    {
                        if (temp < V[j])
                        {
                            V[j + gap] = V[j];
                        }
                        else
                        {
                            break;
                        }
                    }
                    V[j + gap] = temp;
                }   
            }
            gap = gap / 2;
        }
    }
    //====7.3插入排序
    void InsertSort(SortType V[], int length)
    {
        for (int i = 1; i < length; i++)
        {
            if (V[i] < V[i - 1])//比已排序的部分最后一个小
            {
                int j;
                SortType temp = V[i];
                for (j = i - 1; j >= 0; j--)//把该数插入到已排序的部分
                {
                    if (V[j]>temp)
                    {
                        //后移
                        V[j + 1] = V[j];//第一次,覆盖掉未排序的数,
                        //第二次由于最后一个元素(已排序)已经复制了在待排序的位置
                        //依次类推,不会有元素损失                          
                    }
                    else
                    {
                        break;
                    }
                }
                V[j + 1] = temp;
            }
        }
    }
    
    //===7.4归并排序
    /*把两个有序列表合并*/
    void merge(SortType Initlist[], SortType mergeList[], int index_l, int index_mid, int index_r)
    {
        int i = index_l, j = index_mid + 1, k = index_l;//把mid当作List1中的元素,List1(Left-mid) List2(mid+1 right)
        while (i<=index_mid&&j<=index_r)
        {
            if (Initlist[i] <= Initlist[j]) mergeList[k++] = Initlist[i++];
            else                           mergeList[k++] = Initlist[j++];
        }
        while (i <= index_mid) mergeList[k++] = Initlist[i++];
        while (j <= index_r) mergeList[k++] = Initlist[j++];
    }
    /*相邻长度为len的两个有序数组合并*/
    /*合并过程中,有3种情况
    1.完全合并了
    2.过程中单词合并后剩下了,单数
    3.最后,剩下了的部分
    */
    void mergePass(SortType Initlist[], SortType mergeList[], int s /*两个长度为s数组合并*/, int len /*排序数组总长度*/)
    {
        int i = 0;
        while((len-i-1)>=2*s)//把偶数项全部合并,可能留下奇数项
        {
            merge(Initlist, mergeList, i, i + s - 1, i + 2 * s - 1);
            i = i + 2 * s;
        }
        if ((len-i-1)>=s)//最后,不足长度s的合并
            merge(Initlist, mergeList, i, i + s - 1, len - 1);
        else                //前面已经合并,把最后剩下的,直接复制加入
        {
            for (int j = i; j <=len-1 ; j++)
            {
                mergeList[j] = Initlist[j];
            }
        }
    }
    void MergeSort(SortType Initlist[], int length)
    {
        SortType *tempList = (SortType*)malloc(sizeof(SortType)*length);
        int s = 1;
        while (s<length)
        {
            mergePass(Initlist, tempList, s, length);
            s *= 2;
            mergePass(tempList, Initlist, s, length);
            s *= 2;
        }
        free(tempList);
    }
    
    //============交换类排序
    //====7.5冒泡排序
    void BubbleSort(SortType V[], int length)
    {
        for (int i = 1; i <length; i++)
        {
            for (int j = length - 1; j >= i; j--)//每次从最后一个元素开始,直到待排序的位置i
            {
                if (V[j]<V[j - 1])
                {
                    Swap(V[j], V[j - 1]);
                }
            }
        }
    }
    
    //====7.6快速排序
    int Partition(SortType V[], int low,int high)
    {
        SortType pivotkey = V[low];
        while (low<high)
        {
            while (low < high&&V[high] >= pivotkey)high--;
            V[low] = V[high];
        //  Swap(V[low], V[high]);
    
            while (low < high&&V[low] <= pivotkey)low++;
            V[high] = V[low];
        //  Swap(V[low], V[high]);
        }
        V[low] = pivotkey;
        return low;
    }
    void QuickSort(SortType V[], int low, int high)
    {
        while (low < high)
        {
            int keyIndex = Partition(V, low, high);
            QuickSort(V, low, keyIndex -1);
            low = keyIndex + 1;
            //QuickSort(V, keyIndex + 1, high);
        }
    }

    这里写图片描述

  • 相关阅读:
    D. Time to Run【构造】
    P3388 割顶 【求割点个数】
    处女座的测验 素数,构造
    处女座与复读机 DP
    求一个分数小数点后指定位数的数字
    安卓开发创建活动,布局,添加按钮,she使用Toast,设菜单,使菜单相关联等操作
    三进制 处女座的砝码 高精度
    上海高校程序设计联赛 D-CSL的字符串 栈模拟
    区间DP经典 石子合并
    区间DP 洛谷P2858牛奶零食
  • 原文地址:https://www.cnblogs.com/OnMyWay321/p/5093852.html
Copyright © 2011-2022 走看看