链表的常用算法c++

结点定义:struct node
创建无序链表:Create()
遍历链表:Print() Search()
删除结点:Delete_one_node()
释放链表:Delete_chain()
插入一个结点:Insert()
创建有序链表:Create_sort()

#include <iostream>
#include<iomanip>
using namespace std;

/*不带头节点*/

//定义链表结点结构
struct node{
   
    int data;
    node *next;
};

//动态创建无序链表,函数返回值为链表的首指针;程序运行时,依次输入链表中各结点的数据,以输入'-1'表示结束。
node * Create(){
   
    node *p1, *p2 = NULL, *head;//p1指向新开辟的结点,p2指向建立过程中的链表尾结点,head指向链表首结点
    int a;
    head = NULL;//初始时,设置head为空指针

    cout << "正在创建一条无序链表...\n";
    cout << "请输入一个正整数,以-1结束:";
    cin >> a;//输入第一个数据

    while(a != -1){
   
        p1 = new node;//动态申请一个新结点 <指针变量> = new <数据类型> 程序结束前必须通过delete释放
        p1->data = a;//给新结点数据域赋值

        if(head == NULL)//只有第一次加入结点时本条件成立
            head = p2 = p1;//加入首结点
        else{
   
            p2->next = p1;//连入中间结点
            p2 = p1;
        }

         cout << "请输入一个正整数,以-1结束:";
         cin >> a;//输入下一个数据

    }

    if(head != NULL){
   //如建立的不是空链表,则需要进行尾结点处理

        p2->next = NULL;
    }

    return head;//返回链表首指针
}<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kruskal算法是一种最小生成树算法,它的基本思想是将所有的边按照权值从小到大排序,然后依次加入生成树中,如果加入该边不会导致生成树形成环,则加入该边,否则舍去该边。 在Kruskal算法中,需要判断当前加入的边是否会导致生成树形成环。可以使用并查集来实现该功能。具体来说,对于每个节点,维护它的父节点,初始时每个节点的父节点都是它本身。每次加入一条边时,判断该边的两个端点是否在同一个并查集中,如果是,则加入该边会导致生成树形成环,应该舍去该边;否则,将两个端点所在的并查集合并起来,并将该边加入生成树中。 以下是使用链表实现的Kruskal算法判断回路的C++代码: ```cpp #include <iostream> #include <vector> using namespace std; struct Edge { int u, v, w; Edge(int _u, int _v, int _w) : u(_u), v(_v), w(_w) {} }; struct Node { int parent; int rank; Node() : parent(-1), rank(0) {} }; vector<Node> nodes; // 查找节点x所在的集合的代表节点 int find(int x) { if (nodes[x].parent == -1) { return x; } else { return nodes[x].parent = find(nodes[x].parent); } } // 合并x和y所在的集合 void merge(int x, int y) { int root_x = find(x); int root_y = find(y); if (root_x != root_y) { if (nodes[root_x].rank < nodes[root_y].rank) { nodes[root_x].parent = root_y; } else if (nodes[root_x].rank > nodes[root_y].rank) { nodes[root_y].parent = root_x; } else { nodes[root_y].parent = root_x; nodes[root_x].rank++; } } } // 判断加入边(u, v, w)是否形成环 bool hasCycle(int u, int v) { int root_u = find(u); int root_v = find(v); if (root_u == root_v) { return true; } else { merge(root_u, root_v); return false; } } // Kruskal算法求最小生成树 vector<Edge> kruskal(int n, vector<Edge>& edges) { vector<Edge> result; nodes.resize(n); sort(edges.begin(), edges.end(), [](Edge& e1, Edge& e2) { return e1.w < e2.w; }); for (auto& edge : edges) { if (!hasCycle(edge.u, edge.v)) { result.push_back(edge); } } return result; } int main() { int n = 6; vector<Edge> edges = { {0, 1, 4}, {0, 2, 3}, {1, 2, 1}, {1, 3, 2}, {2, 3, 4}, {3, 4, 2}, {4, 5, 6} }; vector<Edge> result = kruskal(n, edges); for (auto& edge : result) { cout << edge.u << " " << edge.v << " " << edge.w << endl; } return 0; } ``` 以上代码中,find函数和merge函数分别实现了并查集中的查找和合并操作。hasCycle函数判断加入边(u, v, w)是否会导致生成树形成环,如果是,则返回true,否则返回false,并且将u和v所在的集合合并起来。kruskal函数实现了Kruskal算法,其中使用sort函数将所有边按照权值从小到大排序,并依次加入生成树中。最后,将生成树的边保存在result向量中,并返回。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值