数据结构基础

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

这里写图片描述

原文地址:https://www.cnblogs.com/OnMyWay321/p/5093852.html