Welcome to LHY's Blog!

数据结构

线性表

顺序表

  1. 初始化
#define InitSize 10

typedef struct
{
    int *data;
    int MaxSize;
    int length;
}SqList;

void InitList(SqList &L)
{
    L.data = (int *)malloc(InitSize * sizeof(int));
    ///L.data = new int[Initsize];
    L.length = 0;
    L.MaxSize = InitSize;
}
  1. 扩容
void IncreaseSize(SqList &L, int Len)
{
    int *p = L.data;
    L.data = (int *)malloc(sizeof(int) * (L.MaxSize + Len));
    for (int i = 0; i < L.length; i ++)
        L.data[i] = p[i];
    L.MaxSize = L.MaxSize + Len;
    free(p);
}
  1. 按位查找
int GetElem(SqList L, int i) //按位查找
{
    return L.data[i - 1];
}
  1. 按值查找
int LocateElem(SqList L, int e)  //按值查找
{
    for (int i = 0; i < L.length; i ++)
    {
        if (L.data[i] == e)
            return i + 1;
    }
    return 0;
}
  1. 按位插入
bool ListInsert(SqList &L, int i, int e) //在L的位序i上插入元素e
{
    if (i < 1 || i > L.length + 1)
        return false;
    if (L.length >= MaxSize)
        return false;
    for (int j = L.length; j >= i; j -- )
    {
        L.data[j] = L.data[j - 1];
    }
    L.data[i - 1] = e;
    L.length ++;
    return true;
}
  1. 按位删除
bool ListDelete(SqList &L, int i, int &e)
{
    if (i < 1 || i > L.length)
        return false;
    e = L.data[i - 1];
    for (int j = i; j < L.length; j ++)
    {
        L.data[j - 1] = L.data[j];
    }
    L.length --;
    return true;
}

单链表

  1. 初始化
typedef struct LNode
{
    int data;
    struct LNode* next;
}LNode, *LinkList;

bool InitLinkList(LinkList &L) //初始化
{
    L = new LNode;
    if (L == NULL) //内存不足,分配失败
        return false;
    L->next = NULL;
    return true;
}
  1. 头插法
LinkList CreateList_Head(LinkList &L, int n) //头插法
{
    L = new LNode;
    L->next = NULL;

    for (int i = 0; i < n; i ++ )
    {
        LNode *p = new LNode;
        cin >> p->data;
        p->next = L->next;
        L->next = p;
    }

    return L;
}
  1. 尾插法
LinkList CreateList_Tail(LinkList &L, int n) //尾插法
{
    L = new LNode;
    L->next = NULL;
    LNode *tail = L;
    for (int i = 0; i < n; i ++ )
    {
        LNode *p = new LNode;
        cin >> p->data;
        tail->next = p;
        p->next = NULL;
        tail = p;
    }

    tail->next = NULL;

    return L;
}
  1. 按位查找
LNode* GetElem(LinkList L, int i) //按位查找
{
    if (i < 0)
        return NULL;
    LNode *p = L;
    int j = 0;
    while (p && j < i)
    {
        p = p->next;
        j ++ ;
    }

    return p;
}
  1. 按值查找
LNode* LocateElem(LinkList &L, int e) //按值查找
{
    LNode *p = L->next; //首元节点
    while (p && p->data != e)
    {
        p = p->next;
    }

    return p; //查找成功返回值为e的节点地址p,查找失败p为NULL
}
  1. 按位插入
bool ListInsert(LinkList L, int i, int e) //按位插入
{
    if (i < 1)
        return false;
    LNode *p;
    if (!(p = GetElem(L, i - 1)))
        return false;
    
    LNode *s = new LNode;
    s->data = e;
    
    s->next = p->next;
    p->next = s;

    return true;
}
  1. 按位删除
bool ListDelete(LinkList L, int i) //按位删除
{
    if (i < 1)
        return false;
    LNode *p;
    if (!(p = GetElem(L, i - 1)))
        return false;
    LNode *q = p->next;
    p->next = q->next;
    delete q;
    return true;
}
  1. 遍历
void Print(LinkList L)
{
    LNode *p = L->next;
    while (p != NULL)
    {
        if (p->next != NULL)
            cout << p->data << " ";
        else
            cout << p->data;
        p = p->next;
    }
}
  1. 判空
bool Empty(LinkList L)
{
    if (L -> next == NULL)
        return true;
    else
        return false;
}

双链表

  1. 初始化
typedef struct DuLNode
{
    int data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode, *DuLinkList;

bool InitDuLinkList(DuLinkList &L) //初始化
{
    L = new DuLNode; //分配一个头节点
    if (L == NULL) //分配失败
        return false;
    L->prior = NULL; //头节点的前指针永远指向NULL
    L->next = NULL; //因为是空表,头节点之后暂时还没有节点

    return true;
}
  1. 头插法
void CreateList_Head(DuLinkList & L, int n) //头插法
{
    L = new DuLNode;
    L->prior = NULL;
    L->next = NULL;
    while (n -- )
    {
        DuLNode* p = new DuLNode;
        cin >> p->data;
        p->next = L->next;
        if (L->next != NULL) L->next->prior = p;
        p->prior = L;
        L->next = p;
    }
}
  1. 尾插法
DuLinkList CreateList_Tail(DuLinkList &L, int n) //尾插法
{
    L = new DuLNode;
    L->next = NULL;
    L->prior = NULL;
    DuLNode *tail = L;
    for (int i = 0; i < n; i ++ )
    {
        DuLNode *p = new DuLNode;
        cin >> p->data;
        p->prior = tail;
        tail->next = p;
        tail = p;
    }

    tail->next = NULL;

    return L;
}
  1. 按位查找
DuLNode* GetElem(DuLinkList L, int i) //按位查找
{
    if (i < 0) return NULL;
    DuLNode *p = L;
    int j = 0;
    while (p && j < i)
    {
        p = p->next;
        j ++ ;
    }

    return p;
}
  1. 按值查找
DuLNode* LocateElem(DuLinkList L, int e) //按值查找
{
    DuLNode *p = L->next;
    while (p && p->data != e)
    {
        p = p->next;
    }
    return p;
}
  1. 按位插入
bool ListInsert(DuLinkList &L, int i, int e) //按位插入
{
    if (i < 1)
        return false;
    DuLNode *p;
    if (!(p = GetElem(L, i))) //第i个元素不存在
        return false;
    DuLNode *s = new DuLNode;
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s;

    return true;
    
}
  1. 按位删除
bool ListDelete(DuLinkList &L, int i) //按位删除
{
    if (i < 1)
        return false;
    DuLNode *p;
    if (!(p = GetElem(L, i))) //第i个元素不存在
        return false;

    p->prior->next = p->next;
    if (p->next != NULL)
        p->next->prior = p->prior;
    
    delete p;

    return true;
}
  1. 遍历
void Print(DuLinkList L)
{
    DuLNode *p = L->next;
    while (p != NULL)
    {
        if (p->next != NULL)
            cout << p->data << " ";
        else
            cout << p->data;
        p = p->next;
    }
}
  1. 判空
bool Empty(DuLinkList L) //判断空表
{
    if (L->next == NULL) return true;
    else return false;
}

循环单链表

  1. 初始化
typedef struct LNode
{
    int data;
    struct LNode* next;
}LNode, *CycleList;
  1. 头插法
void CreateList_Head(CycleList &L, int n)
{
    L = new LNode;
    L->next = L;
    while (n -- )
    {
        LNode* p = new LNode;
        cin >> p->data;
        p->next = L->next;
        L->next = p;
    }
}
  1. 尾插法
void CreateList_Tail(CycleList &L, int n)
{
    L = new LNode;
    L->next = L;
    LNode* tail = L;
    while (n -- )
    {
        LNode* p = new LNode;
        cin >> p->data;
        tail->next = p;
        tail = p;
    }
    tail->next = L;
}
  1. 按位查找
LNode* GetElem(CycleList L, int i)
{
    if (i == 0) return L;
    LNode* p = L->next;
    int j = 1;
    while (p != L && j < i)
    {
        p = p->next;
        j ++ ;
    }
    return p;
}
  1. 按值查找
LNode* LocateElem(CycleList L, int e)
{
    LNode* p = L->next;
    while (p != L && p->data != e)
    {
        p = p->next;
    }
    return p;
}
  1. 插入
void ListInsert(CycleList &L, int i, int e)
{
    LNode* p = GetElem(L, i - 1);
    LNode* s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
}
  1. 删除
void ListDelete(CycleList &L, int i)
{
    LNode* p = GetElem(L, i - 1);
    LNode* q = p->next;
    p->next = q->next;
    delete q;
}
  1. 遍历
void Print(CycleList &L)
{
    LNode* p = L->next;
    while (p != L)
    {
        if (p->next != L)
            cout << p->data << " ";
        else
            cout << p->data;
        p = p->next;
    }
}

循环双链表

  1. 初始化
typedef struct DuLNode
{
    int data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode, *DuCycleList;
  1. 头插法
void CreateList_Head(DuCycleList& L, int n) //头插法
{
    L = new DuLNode;
    L->prior = L;
    L->next = L;
    while (n -- )
    {
        DuLNode* p = new DuLNode;
        cin >> p->data;
        p->next = L->next;
        if (L->next != L) L->next->prior = p;
        p->prior = L;
        L->next = p;
    }
}
  1. 尾插法
void CreateList_Tail(DuCycleList &L, int n) //尾插法
{
    L = new DuLNode;
    L->next = L;
    L->prior = L;
    DuLNode *tail = L;
    for (int i = 0; i < n; i ++ )
    {
        DuLNode *p = new DuLNode;
        cin >> p->data;
        p->prior = tail;
        tail->next = p;
        tail = p;
    }

    tail->next = L;
}
  1. 按位查找
DuLNode* GetElem(DuCycleList L, int i) //按位查找
{
    if (i < 0) return NULL;
    if (i == 0) return L;
    DuLNode *p = L->next;
    int j = 1;
    while (p != L && j < i)
    {
        p = p->next;
        j ++ ;
    }

    return p;
}
  1. 按值查找
DuLNode* LocateElem(DuCycleList L, int e) //按值查找
{
    DuLNode *p = L->next;
    while (p != L && p->data != e)
    {
        p = p->next;
    }
    return p;
}
  1. 插入
bool ListInsert(DuCycleList &L, int i, int e) //按位插入
{
    if (i < 1)
        return false;
    DuLNode *p;
    if (!(p = GetElem(L, i))) //第i个元素不存在
        return false;
    DuLNode *s = new DuLNode;
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s;

    return true;
}
  1. 删除
bool ListDelete(DuCycleList &L, int i) //按位删除
{
    if (i < 1)
        return false;
    DuLNode *p;
    if (!(p = GetElem(L, i))) //第i个元素不存在
        return false;

    p->prior->next = p->next;
    if (p->next != L)
        p->next->prior = p->prior;
    
    delete p;

    return true;
}
  1. 遍历
void Print(DuCycleList L)
{
    DuLNode *p = L->next;
    while (p != L)
    {
        if (p->next != L)
            cout << p->data << " ";
        else
            cout << p->data;
        p = p->next;
    }
}

顺序栈

  1. 初始化
#define MAXSIZE 100

typedef struct
{
    int *base; //栈底指针
    int *top; //栈顶指针
    int stacksize; //栈可用最大容量
}SqStack;

bool InitStack(SqStack &S)
{
    S.base = new int[MAXSIZE]; //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
    if (!S.base) return false; //存储分配失败
    S.top = S.base; //top初始为base,空栈
    S.stacksize = MAXSIZE; //栈的最大容量
    return true;
}
  1. 入栈
bool Push(SqStack &S, int e)
{
    if (S.top - S.base == S.stacksize) //栈满
        return false;
    *S.top ++ = e; //将元素e压入栈顶,栈顶指针加1
    return true;
}
  1. 出栈
bool Pop(SqStack &S, int &e)
{
    if (S.top == S.base) //栈空
        return false;
    e = *--S.top; //将栈顶指针减1,将栈顶指针赋给e
    return true;
}
  1. 取栈顶元素
int GetTop(SqStack &S)
{
    if (S.top != S.base) //栈不空
        return *(S.top - 1); //返回栈顶元素的值,不修改栈顶指针
    else return -1;
}

链栈

  1. 初始化
typedef struct StackNode
{
    int data;
    struct StackNode *next;
}StackNode, *LinkStack;

bool InitStack(LinkStack &S) //无需设立头节点
{
    S = NULL;
    return true;
}
  1. 入栈
bool Push(LinkStack &S, int e)
{
    StackNode *p = new StackNode;
    p->data = e;
    p->next = S;
    S = p;
    return true;
}
  1. 出栈
bool Pop(LinkStack &S, int &e)
{
    if (S == NULL) //空
		return false;
    e = S->data;
    StackNode *p = S;
    S = S->next;
    delete p;

    return true;
}
  1. 取栈顶元素
int GetTop(LinkStack &S)
{
    if (S!= NULL) //不空
        return S->data;
}

队列

循环队列

  1. 初始化
#define MAXSIZE 100

typedef struct
{
    int *base;
    int front;
    int rear;
}SqQueue;

bool InitQueue(SqQueue &Q)
{
    Q.base = new int[MAXSIZE];
    if (!Q.base) return false;
    Q.front = Q.rear = 0;
    return true;
}
  1. 求循环队列长度
int QueueLength(SqQueue Q)
{
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; //防止长度为负数
}
  1. 入队
bool EnQueue(SqQueue &Q, int e)
{
    if ((Q.rear + 1) % MAXSIZE == Q.front) //队列满了
        return false;

    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXSIZE;
    return true;
}
  1. 出队
bool DeQueue(SqQueue &Q, int &e)
{
    if (Q.front == Q.rear) //队列空
        return false;
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXSIZE;

    return true;
}
  1. 取队头元素
int GetHead(SqQueue Q)
{
    if (Q.front != Q.rear) //队列不空
        return Q.base[Q.front];
}

链队

  1. 初始化
typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode, *QueuePtr;

typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

bool InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = new QNode;
    Q.front->next = NULL;
    return true;
}
  1. 入队
bool EnQueue(LinkQueue &Q, int e)
{
    QNode *p = new QNode;
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return true;
}
  1. 出队
bool DeQueue(LinkQueue &Q, int &e)
{
    if (Q.front == Q.rear) return false;
    QNode *p = Q.front->next; //指向队头元素
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) Q.rear = Q.front; //如果最后一个元素被删,队尾指针指向头节点
    delete p;
    return true;
}
  1. 取队头元素
int GetHead(LinkQueue Q)
{
    if (Q.front != Q.rear)
        return Q.front->next->data;
    return -1;
}

普通二叉树

  1. 定义
typedef struct TNode
{
    int data;
    struct TNode* left;
    struct TNode* right;
}TNode, *BinTree;
  1. 先序创建二叉树
//先序创建二叉树
void CreateBinTree(BinTree &T)
{
    int x;
    cin >> x;
    if (x == -1)
    {
        T = NULL;
        return;
    }
    else
    {
        T = new TNode;
        T->data = x;
        CreateBinTree(T->left);
        CreateBinTree(T->right);
    }
}
  1. 层序创建二叉树
void build(BinTree &T)
{
    TNode* q[N];
    int hh = 0, tt = -1;
    int x;

    cin >> x; //根节点
    if (x != -1)
    {
        T = new TNode;
        T->data = x;
        q[++tt] = T;
    }
    else
    {
        T = NULL;
        return;
    }

    while (hh <= tt)
    {
        TNode* t = q[hh ++ ];
        cin >> x; //左儿子
        if (x != -1)
        {
            t->left = new TNode;
            t->left->data = x;
            q[++tt] = t->left;
        }
        else t->left = NULL;
        cin >> x; //右儿子
        if (x != -1)
        {
            t->right = new TNode;
            t->right->data = x;
            q[++tt] = t->right;
        }
        else t->right = NULL;
    }
}
  1. 先序、中序、后序、层序遍历
//先序遍历
void PreOrder(BinTree T)
{
    if (T)
    {
        cout << T->data << " ";
        if (T->left) PreOrder(T->left);
        if (T->right) PreOrder(T->right);
    }
}

//中序遍历
void InOrder(BinTree T)
{
    if (T)
    {
        if (T->left) InOrder(T->left);
        cout << T->data << " ";
        if (T->right) InOrder(T->right);
    }
}

//后序遍历
void PostOrder(BinTree T)
{
    if (T)
    {
        PostOrder(T->left);
        PostOrder(T->right);
        cout << T->data << " ";
    }
}

//层序遍历
void bfs(BinTree T)
{
    TNode* q[N];
    int hh = 0, tt = -1;
    if (T) q[++tt] = T;
    while (hh <= tt)
    {
        TNode* t = q[hh ++ ];
        cout << t->data << " ";
        if (t->left) q[++tt] = t->left;
        if (t->right) q[++tt] = t->right;
    }
}
  1. 计算二叉树的总结点数量
int NodeCount(BinTree &T)
{
    if (T == NULL) return 0;
    else return NodeCount(T->left) + NodeCount(T->right) + 1;
}
  1. 计算二叉树的叶子节点总数
int LeafCount(BinTree &T)
{
    if (T == NULL) return 0;
    if (T->left == NULL && T->right == NULL) return 1;
    else return LeafCount(T->left) + LeafCount(T->right);
}
  1. 计算二叉树的高度
int GetHeight(BinTree BT)
{
    int HL, HR, ans;
    if (BT)
    {
        HL = GetHeight(BT->Left);
        HR = GetHeight(BT->Right);
        ans = (HL > HR ? HL : HR) + 1;
        return ans;
    }
    else return 0; //空树高度为0
}

线索二叉树

  1. 中序线索二叉树
#include <bits/stdc++.h>

using namespace std;

typedef struct TNode
{
    int data;
    struct TNode* left;
    struct TNode* right;
    int ltag, rtag;
}TNode, *BinTree;

TNode* pre;

//先序创建二叉树
void CreateBinTree(BinTree &T)
{
    int x;
    cin >> x;
    if (x == -1)
    {
        T = NULL;
        return;
    }
    else
    {
        T = new TNode;
        T->data = x;
        CreateBinTree(T->left);
        CreateBinTree(T->right);
    }
}

//以节点p为根的子树线中序线索化
void Inthreading(BinTree& p)
{
    if (p)
    {
        Inthreading(p->left);
        if (!p->left)
        {
            p->ltag = 1;
            p->left = pre;
        }
        else p->ltag = 0;
        if (!pre->right)
        {
            pre->rtag = 1;
            pre->right = p;
        }
        else pre->rtag = 0;
        pre = p;
        Inthreading(p->right);
    }
}

//带头结点的二叉树中序线索化
void InOrderthreading(BinTree& Thrt, BinTree T)
{
    Thrt = new TNode;
    Thrt->ltag = 0; //若树非空,则头节点的左孩子为根节点
    Thrt->rtag = 1;
    Thrt->right = Thrt; //初始化时右指针指向自己
    if (!T) Thrt->left = Thrt; //若树为空,则左指针也指向自己
    else
    {
        Thrt->left = T; //头节点的左孩子指向根节点
        pre = Thrt; //pre的初值指向头节点
        Inthreading(T); //对以T为根的二叉树进行中序线索化
        pre->rtag = 1; //Inthreading结束之后,pre为最右节点,pre的右线索指向头节点
        pre->right = Thrt;
        Thrt->right = pre; //头节点的右线索指向pre??????????
    }
}

//遍历中序二叉树
void InOrderTraverse(BinTree& T) //T为头节点
{
    TNode* p = T->left; //p指向根节点
    while (p != T) //空树或者遍历结束时,p==T
    {
        while (p->ltag == 0) p = p->left; //沿左孩子向下找到左子树为空的点
        cout << " " << p->data;
        
        while (p->rtag == 1 && p->right != T) //沿右线索访问后继节点
        {
            p = p->right;
            cout << " " << p->data;
        }

        p = p->right; //转向p的右子树
    }
}

int main()
{
    //建立普通二叉树
    BinTree T1;
    CreateBinTree(T1);

    //建立中序线索二叉树
    BinTree T2;
    InOrderthreading(T2, T1);

    //遍历中序线索二叉树
    InOrderTraverse(T2);

    return 0;
}
posted @ 2023-09-19 20:37  LiHaoyu  阅读(32)  评论(0)    收藏  举报