进阶算法(二) 《算法笔记》自定义实现1、栈 2、队列 3、链表 4、图 5、DFS深度优先搜索 6、BFS广度优先搜索

1、栈

#include <cstdio>
#include <stack> //STL中栈没有提供清空栈 结束时手动清空
#define MAXLEN 100
namespace Wang
{
    class Stack
    {
    private:
        int *arr;
        int top; // 当前栈顶位置(最后一个元素的位置)
    public:
        Stack()
        {
            arr = new int[MAXLEN];
            this->top = -1;
        }
        bool Empty()
        {
            return top == -1;
        }
        void push(int val)
        {
            arr[top + 1] = val;
            top++;
        }
        void pop()
        {
            if (!Empty())
                top--;
            else
                return;
        }
        int get_top()
        {
            if (!Empty())
                return arr[top];
            else
                return -1;
        }
        int num_stack()
        {
            return top + 1;
        }
        void clear()
        {
            while (!Empty())
                pop();
        }
        ~Stack()
        {
            delete [] arr;
        }
    };
};

int main()
{
    Wang::Stack st;
    if (st.Empty())
        printf("stack is empty ");
    printf("num = %d\n", st.num_stack());
    printf("1入栈: ");
    st.push(1);
    if (!st.Empty())
        printf("stack top = %d ", st.get_top());
    printf("num = %d\n", st.num_stack());
    printf("3入栈: ");
    st.push(3);
    if (!st.Empty())
        printf("stack top = %d ", st.get_top());
    printf("num = %d\n", st.num_stack());
    printf("5入栈: ");
    st.push(5);
    if (!st.Empty())
        printf("stack top = %d ", st.get_top());
    printf("num = %d\n", st.num_stack());
    printf("出栈: ");
    st.pop();
    if (!st.Empty())
        printf("stack top = %d ", st.get_top());
    printf("num = %d\n", st.num_stack());
    printf("清空栈: ");
    st.clear();
    if (!st.Empty())
        printf("stack top = %d ", st.get_top());
    printf("num = %d\n", st.num_stack());

    return 0;
}

2、队列 

#include <cstdio>
#define MAXLEN 100
namespace Wang
{
    class Queue
    {
    private:
        int * arr;
        int head;//头//首元的前一个
        int rear;//尾//尾元
    public:
        Queue()
        {
            arr = new int[MAXLEN];
            head = rear = -1;
        }
        bool Empty()
        {
            return head == rear;
        }
        void push(int val)
        {
            arr[rear + 1] = val;
            rear++;
        }
        void pop()
        {
            if (!Empty())
                head++;
            else
                return;
        }
        int num_queue()
        {
            return rear - head;
        }
        int get_head()
        {
            if (!Empty())
                return arr[head + 1];
            else
                return -1;
        }
        int get_rear()
        {
            if (!Empty())
                return arr[rear];
            else
                return -1;
        }
        void clear()
        {
            if (!Empty())
                rear = head = -1;
            else
                return;
        }
        ~Queue()
        {
            delete [] arr;
        }
    };
};

int main()
{
    Wang::Queue q;
    if (q.Empty())
        printf("空:\n");
    printf("2入队: ");
    q.push(2);
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("5入队: ");
    q.push(5);
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("1入队: ");
    q.push(1);
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("2出队: ");
    q.pop();
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("5出队: ");
    q.pop();
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("清空: ");
    q.clear();
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());
    printf("7入队: ");
    q.push(7);
    printf("队列元素个数: %d 队头 = %d 队尾 = %d\n", q.num_queue(), q.get_head(), q.get_rear());

    return 0;
}

3、链表 

#include <cstdio>
#include <stdlib.h>
struct node
{
    int data;
    node * next;
};
//创建链表
node * Creat(int Array[])
{
    node * p, *pre, *head;
    // head = new node;
    head = (node *)malloc(sizeof(node));
    head->next = NULL; //初始化头节点
    pre = head;
    for (int i = 0; i < 5; ++i)
    {
        // p = new node;
        p = (node *)malloc(sizeof(node));
        p->data = Array[i]; //每一轮 开辟1个节点
        p->next = NULL;
        pre->next = p; //前一个节点指向该节点
        pre = p; //更新前一个节点
    }
    return head;
}
//查找元素
int Search(node * L, int val)
{
    node * p = L->next; //从首元开始找
    int index = 0;
    while (p)
    {
        if (p->data == val)
            return index;
        p = p->next;
        ++index;
    }
    return -1;
}
//第i个位置插入
void Insert(node * L, int pos, int x)
{
    node * p = L->next;
    node * tmp = new node;
    tmp->data = x;
    tmp->next = NULL;
    int index;
    for (index = 1; index < pos; ++index)
        p = p->next;
    tmp->next = p->next;
    p->next = tmp;
}
//删除链表中值为val的节点
void del(node * L, int val)
{
    node * p = L, *pre = NULL;
    while (p->next)
    {
        if (p->next->data == val)
        {
            pre = p;
            break;
        }
        p = p->next;
    }
    if (pre)
    {
        pre->next = p->next->next;
        delete p->next;
    }
    else
        return;
}

int main()
{
    int Array[5] = {5, 3, 6, 1, 2};
    node * L = Creat(Array);
    node * p = L->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }    
    printf("\n");
    printf("5在%d号位置\n", Search(L, 5));
    printf("1在%d号位置\n", Search(L, 1));
    printf("在第3个位置插入99\n");
    Insert(L, 3, 99);
    p = L->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }    
    printf("\n");
    printf("1在%d号位置\n", Search(L, 1));
    printf("删除值为2的元素:\n");
    del(L, 2);
    p = L->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }    
    printf("\n");
    //释放链表
    p = L;
    node * tmp = NULL;
    while (p)
    {
        tmp = p->next;
        free(p);
        p = tmp;
    }

    return 0;
}

4、 图及DFS深度优先遍历

#include <cstdio>
#include <iostream>
// 图G = ({Vertex}, {Edge});
// 顶点集n个顶点 边集(2个顶点之间是否有边)(二维矩阵n*n)
const int VertexMaxNum = 100; // 顶点最大个数100个
struct Graph
{
    char Vertex[VertexMaxNum];            // 顶点集
    int cur_v;                            // 现有的顶点数
    int Edge[VertexMaxNum][VertexMaxNum]; // 边集
    int cur_e;                            // 现有的边的数目
};
// 建立图
void Creat_Graph(Graph &G)
{
    // 0、确定有多少个顶点
    int VertexNum;
    printf("输入顶点个数:");
    std::cin >> VertexNum;
    G.cur_v = VertexNum; // 顶点数
    G.cur_e = 0; //边数
    // 1、输入所有顶点的值
    printf("输入顶点的值:\n");
    int i, j;
    for (i = 0; i < VertexNum; ++i)
        std::cin >> G.Vertex[i];
    // 2、输入所有边 n * n二维数组 1代表顶点i和顶点j之间有边 0代表顶点i和顶点j之间无边
    for (i = 0; i < G.cur_v; ++i)
    {
        printf("输入邻接矩阵第%d行:\n", i + 1);
        for (j = 0; j < G.cur_v; ++j)
        {
            std::cin >> G.Edge[i][j];
            ++G.cur_e;
        }
    }
}
int visited[VertexMaxNum] = {0}; // 初始化为0--代表所有顶点均未被访问过
// 图的深度遍历DFS(Depth First Search)
void DFS(Graph G, int v) // 从v顶点出发--编号规则
{
    // 1、从顶点v出发 访问数组visited[v] = 1;
    // 2、访问邻接矩阵第v行 第一个非0元素且未被访问过
    //重复1、2、== 从第一个非0元素且未被访问过的顶点出发
    printf("%c ", G.Vertex[v]); // 输出该顶点信息
    visited[v] = 1; // 访问数组中对应位置置1
    for (int i = 0; i < G.cur_v; ++i) //查询该顶点的邻接矩阵
    {
        if (G.Edge[v][i] == 1 && visited[i] != 1) // 从第一个非0元素且未被访问过的顶点
            DFS(G, i); //从该顶点出发
    }
}

int main()
{
    int i, j;
    Graph G;
    Creat_Graph(G);
    printf("所有顶点:\n");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n邻接矩阵:\n");
    for (i = 0; i < G.cur_v; ++i)
    {
        printf("\n");
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
    }
    printf("\n");
    DFS(G, 0);

    return 0;
}

4、n件物品DFS 

#include <cstdio>
#include <iostream>
#include <unistd.h>
#define MaxPound 10
#define MaxNum 5
void DFS(int value[], int pound[], int CurSumVal, int CurSumPound, int index)
{
    //出口
    if (index == MaxNum || CurSumPound == MaxPound)
    {
        printf("总价值: %d 总重量 % d\n", CurSumVal, CurSumPound);
        return ;
    }
    //从一堆物品中进行挑选 编号为index的物品选还是不选
    if (CurSumPound + pound[index] > MaxPound)
    {
        //超重, 不选这件 进行下一个编号选择
        DFS(value, pound, CurSumVal, CurSumPound, index + 1);
    }
    else
    {
        //选择这件物品 更新总重量 总价值 进行下一个编号选择
        printf("Choose %d pound = %d value = %d\n", index, pound[index], value[index]);
        DFS(value, pound, CurSumVal + value[index], CurSumPound + pound[index], index + 1);
    }
}

int main()
{
    printf("物品的数量: ");
    int n, i, pound[n], value[n];
    scanf("%d", &n);
    printf ("每件物品的重量: ");
    for (i = 0; i < n; ++i)
        scanf("%d", &pound[i]);
    printf ("每件物品的价值: ");
    for (i = 0; i < n; ++i)
        scanf("%d", &value[i]);
    printf("物品信息:\n");
    for (i = 0; i < n; ++i)
        printf("价值 %d 重量 %d\n", value[i], pound[i]);
    DFS(value, pound, 0, 0, 0);

    return 0;
}

5、BFS广度优先搜索 

#include <cstdio>
#include <iostream>
#include <queue>
#define MAXLEN 100
struct Graph
{
    char Vertex[MAXLEN];
    int Edge[MAXLEN][MAXLEN];
    int cur_v;
    int cur_e;
};
void Create(Graph &G)
{
    int vertex_num, i, j;
    printf("顶点的数目: ");
    std::cin >> vertex_num;
    G.cur_v = vertex_num;
    G.cur_e = 0;
    printf("顶点的值: \n");
    for (i = 0; i < vertex_num; ++i)
        std::cin >> G.Vertex[i];
    printf("边的值: \n");
    for (i = 0; i < vertex_num; ++i)
    {
        printf("第%d行:\n", i + 1);
        for (j = 0; j < vertex_num; ++j)
        {
            std::cin >> G.Edge[i][j];
            ++G.cur_e;
        }
    }
}
// 广度优先
int visited[MAXLEN] = {0};
void BFS(Graph G, int v)
{
    // 1、从v顶点出发, v顶点进入队列
    // 2、若队列非空, v出队, v的所有邻接顶点入队
    //  队列空---结束
    int i, j;
    std::queue<int> q;
    q.push(v);
    printf("%c\n", G.Vertex[v]);
    visited[v] = 1;
    while (!q.empty())
    {
        j = q.front();
        q.pop();
        // 查询邻接矩阵第j行 v的邻接点入队
        for (i = 0; i < G.cur_v; ++i)
        {
            if (G.Edge[j][i] == 1 && visited[i] != 1)
            {
                printf("%c\n", G.Vertex[i]);
                q.push(i);
                visited[i] = 1;
            }
        }
    }
    printf("\n");
    return;
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    printf("顶点信息:\n");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n");
    printf("边信息:\n");
    for (i = 0; i < G.cur_v; ++i)
    {
        printf("\n第 %d 行: ", i + 1);
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
    }
    printf("\n");
    BFS(G, 0);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪呈祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值