数据结构基础

来源:互联网 发布:淘宝网匹克运动装 编辑:程序博客网 时间:2024/05/21 11:05

//==========================================
// 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 100typedef 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 100typedef 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);    }}

这里写图片描述

0 0
原创粉丝点击