DS复习提纲模版

数组的插入删除 

int SeqList::list_insert(int i, int item) { //插入if (i < 1 || i > size + 1 || size >= maxsize) {return 0;  // Invalid index or list is full}for (int j = size-1; j >= i-1; j--) {  // Shift elements to the rightlist[j+1] = list[j];}list[i - 1] = item;  // Insert the item at position i-1size++;  // Increase sizereturn 1;
}
int SeqList::list_del(int i) {  //删除if (i < 1 || i > size) {return 0;  // Invalid index}for (int j = i; j < size; j++) {  // Shift elements to the leftlist[j-1] = list[j];}size--;  // Decrease sizereturn 1;
}

链表操作 

#include <iostream>
using namespace std;
#define ok 0
#define error -1
//链表结点类定义
class ListNode {
public:int data;ListNode* next;ListNode() : data(0), next(NULL) {}
};
//带头结点的单链表定义
class LinkList {
public:ListNode* head;int len;LinkList() : head(new ListNode()), len(0) {}~LinkList();ListNode* LL_index(int i);int LL_get(int i);int LL_insert(int i, int item);int LL_del(int i);void LL_display();
};
LinkList::~LinkList() {ListNode* p, * q;p = head;while (p != NULL) {q = p;p = p->next;delete q;}len = 0;head = NULL;
}
void LinkList::LL_display() {ListNode* p = head->next;while (p) {cout << p->data << ' ';p = p->next;}cout << endl;
}
ListNode* LinkList::LL_index(int i) {int h = 0;ListNode* p = head;while (p && h < i) {p = p->next;h++;}return p;
}
int LinkList::LL_insert(int i, int item) {if (i < 0 || i > len)return error;ListNode* p = head;for (int h = 0; h < i; ++h) {p = p->next;}ListNode* s = new ListNode();s->data = item;s->next = p->next;p->next = s;++len;return ok;
}
int LinkList::LL_get(int i) {if (i < 1 || i > len)return error;ListNode* p = head->next;for (int h = 1; h < i; ++h) {p = p->next;}return p->data;
}
int LinkList::LL_del(int i) {if (i < 1 || i > len)return error;ListNode* p = head;for (int h = 0; h < i - 1; ++h) {p = p->next;}ListNode* s = p->next;p->next = s->next;//头尾相等 空delete s;--len;return ok;
}//两个节点交换位置  需要交换这两个节点的前驱跟后继指针来完成
void LinkList::swap(ListNode* p, ListNode* q) {// 找到p和q的前驱节点ListNode* prevP = head;while (prevP != NULL && prevP->next != p) {prevP = prevP->next;}ListNode* prevQ = head;while (prevQ != NULL && prevQ->next != q) {prevQ = prevQ->next;}// 如果p或q不在链表中,或者它们是头节点(没有前驱),则无法交换if (prevP == NULL || prevQ == NULL) {return;}if (p == NULL || q == NULL)return;//p q是相邻的if (p->next == q) {p->next = q->next;q->next = p;prevP->next = q;}else {// 交换prevP和prevQ的下一个节点的指针ListNode* temp = p->next;p->next = q->next;q->next = temp;// 交换p和q的指针temp = prevP->next;prevP->next = prevQ->next;prevQ->next = temp;}
}
//链表的合并
ListNode* LL_merge1(ListNode* p, ListNode* q) {ListNode* preHead = new ListNode();ListNode* prev = preHead;while (p && q) {if (p->data < q->data) {prev->next = p;p = p->next;}else if (p->data > q->data) {prev->next = q;q = q->next;}else {prev->next = q;p = p->next;q = q->next;}prev = prev->next;}prev->next = q ? q : p;//更长的那一段的剩余的直接截取接至新链表//pre->next = p ? p : q;return preHead->next;
}
//删除链表相同元素--与先存进来的元素互异后才可存入链表
#include<iostream>
using namespace std;
// 定义链表节点结构体LNode
typedef struct LNode {int data;             // 节点存储的数据struct LNode* next;   // 指向下一个节点的指针
} LNode, * Linklist;     // LNode为节点类型,Linklist为指向节点的指针类型
int main() {int t;cin >> t;             // 读取测试用例的数量while (t--) {         // 对每个测试用例进行处理int n;cin >> n;         // 读取链表长度Linklist L;L = new LNode;    // 创建头节点L->next = NULL;   // 初始化头节点的next指针为NULLLNode* r = L;     // r指针用于指向链表的最后一个节点// 循环读取n个数据,并插入到链表中for (int i = 0; i < n; i++) {int num;cin >> num;       // 读取一个数据LNode* tmp = L;   // tmp指针用于遍历链表  L是一整个链表bool dup = false; // 标记是否发现重复数据// 遍历链表,检查num是否已存在while (tmp) {if (tmp->data == num) {dup = true; // 发现重复数据break;      // 退出循环}tmp = tmp->next;}// 如果num已存在,则跳过插入操作if (dup) {continue;}else {// 创建新节点并插入到链表末尾r->next = new LNode;r->next->data = num; // 设置新节点的数据r = r->next;         // 更新r指针r->next = nullptr;   // 设置新节点的next指针为NULL}}// 计算链表长度int len = 0;LNode* p = L->next;  // p指针用于遍历链表LNode* q = L->next;  // q指针也用于遍历链表while (q != NULL) {  // 遍历链表计算长度q = q->next;len++;}// 这里删除q是错误的,因为q已经是NULL,不需要删除// delete q;// 输出链表长度和链表数据cout << len << ":";while (p != NULL) {  // 遍历链表并输出数据cout << " " << p->data;p = p->next;}// 这里删除p是错误的,因为p指向的是头节点的下一个节点// 应该遍历整个链表并删除每个节点// delete p;cout << endl;// 释放链表内存LNode* toDelete = L;while (toDelete != NULL) {LNode* next = toDelete->next;delete toDelete;toDelete = next;}}return 0;
}

栈(先进后出)

// 行编辑
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main() {int t;cin >> t;while (t--) {string str;cin >> str;     // 把输入的字符串保存在变量str中int len = str.length();        // 获取输入字符串的长度stack<char> s;for (int m = 0; m < len; m++) {char ch = str[m]; // 读取当前字符if (ch != '#') {s.push(ch); // 如果不是 '#',则压入栈 s}else if(ch=='#'&& !s.empty()){s.pop();}}if (s.empty()) {cout << "NULL" << endl;}while (!s.empty()) {cout << s.top();s.pop();}cout << endl;}return 0;
}

波兰式与逆波兰式

#include<iostream>
#include<string>
#include<stack>
using namespace std;
class Solution
{
private:stack<string> nums;		// 存储操作数, 实际上会存储操作符的stack<char> op;			// 存储操作符// 逆向遍历时判断操作符优先级bool opcmpRight(char op1, char op2){// + - 的时候,只需要判断栈顶是否同级,逆序,同级新的优先级更高if (op1 == '+' || op1 == '-'){return op2 == '+' || op2 == '-';}// * / 直接入栈return true;}// 正向遍历时判断操作符优先级bool opcmpLeft(char op1, char op2){// 正向的时候,同级新的优先级会低if (op1 == '*' || op1 == '/'){return op2 != '*' && op2 != '/';}return false;}
public:string poland(string s)// 求解波兰式{int len = s.length();for (int i = len - 1; i >= 0; --i){if (s[i] >= '0' && s[i] <= '9'){string num = "";num += s[i];while (i - 1 >= 0 && s[i - 1] >= '0' && s[i - 1] <= '9'){num = s[--i] + num;}nums.push(num);}else if (op.empty() || s[i] == ')' || op.top() == ')'){op.push(s[i]);}else if (s[i] == '('){while (!op.empty() && op.top() != ')'){string ops = "";ops += op.top();nums.push(ops);op.pop();}op.pop();}else if (opcmpRight(s[i], op.top())){op.push(s[i]);}else{while (!op.empty() && !opcmpRight(s[i], op.top())){string ops = "";ops += op.top();nums.push(ops);op.pop();}op.push(s[i]);}}while (!op.empty()){string ops = "";ops += op.top();nums.push(ops);op.pop();}string ans = "";while (!nums.empty()){ans += nums.top() + (nums.size() > 1 ? " " : "");nums.pop();}return ans;}string antiPoland(string s){int len = s.size();string ans = "";for (int i = 0; i < len; ++i){if (s[i] >= '0' && s[i] <= '9'){ans += s[i];while (i + 1 < len && s[i + 1] >= '0' && s[i + 1] <= '9'){ans += s[++i];}ans += " ";}else if (op.empty() || s[i] == '(' || op.top() == '('){op.push(s[i]);}else if (s[i] == ')'){while (!op.empty() && op.top() != '('){ans += op.top();ans += " ";op.pop();}op.pop();}else if (opcmpLeft(s[i], op.top())){op.push(s[i]);}else{while (!op.empty() && !opcmpLeft(s[i], op.top())){ans += op.top();ans += " ";op.pop();}op.push(s[i]);}}while (!op.empty()){ans += op.top();ans += op.size() > 1 ? " " : "";op.pop();}return ans;}
};
int main()
{int t;cin >> t;while (t--){Solution sol;string s;cin >> s;cout << sol.poland(s) << endl;cout << sol.antiPoland(s) << endl << endl;} return 0;
}

队列(先进先出)

#include<iostream>
#include<queue>
#include<utility>
#include<vector>
#include<iomanip>
#include<algorithm>
using namespace std;
int main()
{int n;cin >> n;// 用户队列queue<pair<int, int>> customer;for (int i = 0; i < n; i++){int time1, time2;cin >> time1 >> time2;customer.push({ time1, time2 });}int k;cin >> k;// 初始化窗口vector<int> windows(k, 0);// 总时间,完成时间,和最大等待时间int totalWaitTime = 0, finishTime = 0, maxWaitTime = 0;while (!customer.empty()){int arriveTime = customer.front().first;int takenTime = customer.front().second;// 默认最早空闲的窗口的最小下标int minIndex = 0;for (int i = 0; i < k; ++i){// 窗口在到达时间之前空闲if (windows[i] <= arriveTime){minIndex = i;break;}// 动态更新下标if (windows[i] < windows[minIndex]){minIndex = i;}}// 最早空闲的窗口先于到达时间if (windows[minIndex] <= arriveTime){windows[minIndex] = arriveTime + takenTime;}// 否则则需要等待else{int wait = windows[minIndex] - arriveTime;windows[minIndex] += takenTime;totalWaitTime += wait;maxWaitTime = max(maxWaitTime, wait);}// 完成时间取最大值finishTime = max(finishTime, windows[minIndex]);customer.pop();}cout << fixed << setprecision(1) << (double)(totalWaitTime * 1.0 / n)<< " " << maxWaitTime << " " << finishTime << endl;return 0;
}

 串

//真前后缀
#include <iostream>
#include <string>
using namespace std;
string matchedPrefixPostfix(string str) {int n = str.length();string result = "empty";if (n > 1) {for (int i = 0; i < n; ++i) {for (int j = 0; j <= n - i - 1; ++j) {string prefix = str.substr(0, i + 1);//提取子串 正向string postfix = str.substr(n - j - 1, j + 1);// 提取子串 逆向if (prefix == postfix) {result = prefix;}}}}return result;
}
int main() {int t;cin >> t;while (t--) {string str;cin >> str;cout << matchedPrefixPostfix(str) << endl;}return 0;
}

查找

//直接插入排序
void InsertSort(int array[], int length) {for (int i = 1; i < length; i++) {		//第1个数是有序的,所以从第2个数开始遍历,依次插入int j = i - 1;					//前i-1个数都是有序序列(由小到大),只要a[j]比temp大,就将此数后移int temp = array[i];		//先将当前的数存储在temp后,以免后面移位被覆盖for (j = i - 1; j >= 0 && array[j] > temp; j--) {//a[j]小于 temp 时循环结束,结束后应将 temp 赋值给a[j+1]array[j + 1] = array[j];	//将 a[j] 后移一位 }array[j + 1] = temp;			//将 temp 赋值给a[j+1]Print(array, length);}
}//希尔排序
void find(int* a, int n) {int b = n / 2;while (b >= 1) {for (int i = b; i < n; i++) {int  tmp = a[i];int j = i;while (j >= b && a[j - b] < tmp) {a[j] = a[j - b];j -= b;}a[j] = tmp;}for (int i = 0; i < n-1; i++) {cout << a[i] << " ";}cout << a[n-1]<<endl;b = b / 2;}
}
//冒泡排序
void bubble_sort(int * arr, int len) 
{int i, j;int k = 0;for (i = 0; i < len - 1; i++)for (j = 0; j < len - 1 - i; j++)if (arr[j] > arr[j + 1]){swap(arr[j], arr[j + 1]);k++;}cout << k << endl;
}
//快速排序
int Partition(int * &array, int low, int high){int mid_key= array[low];//记录枢轴的值while(low< high){while(low< high&&array[high]>= mid_key )high--;array[low]= array[high];//大于枢轴的值前移while(low< high&&array[low]<= mid_key)low++;array[high]= array[low];  //小于枢轴的值后移    }array[low]= mid_key;//最后才将枢轴的值记录到位return low;  //返回枢轴的位置
}
void print(int * &array){//打印输出for(int i= 1; i<= n; i++){cout<<array[i];if(i!= n)cout<<' ';elsecout<<endl; }   
}
void Qsort(int* &array, int low, int high){//快速排序if(low< high){int mid= Partition(array, low, high);print(array);Qsort(array, low, mid- 1);//将数组分成[low,mid-1]和[mid,high]两个区间Qsort(array, mid+ 1, high);//}
}

树--叶子

//二叉树找父子节点
#include <iostream>
#include<queue>
using namespace std;
typedef struct BitNode {char data;BitNode* lchild, * rchild;
}BitNode, * BitTree;
void CreatTree(BitTree& T) {char ch;cin >> ch;if (ch == '/0') { return; }if (ch == '0') { T = NULL; }else {T = new BitNode;T->data = ch;/*先左后右保存数据**/CreatTree(T->lchild);CreatTree(T->rchild);}
}
int FindLeaf(BitTree& T, queue<char>& child, queue<char>& parent) {if (!T) { return 1; }int flag = 0;//统计叶子if (T) {int item = FindLeaf(T->lchild, child, parent);//记录左儿子是不是叶子if (item == 0) {parent.push(T->data);}else if (item == 1) {flag++;}item = FindLeaf(T->rchild, child, parent);if (item == 0) {parent.push(T->data);}else if (item == 1) {flag++;}}if (flag == 2) {child.push(T->data);return 0;}return -1;//未找到叶子
}
//统计左叶子
void LeftLeaf(BitTree& T,int & cnt,bool isleft) {//是否为空//是否为叶子//对左叶子进行布尔值改变//对右叶子不做布尔值变化if (!T) { return ; }  //空的标记return	if (!T->lchild&&!T->rchild) {if(isleft)cnt++;}LeftLeaf(T->lchild, cnt, true);LeftLeaf(T->rchild, cnt,false);
}

树的遍历

#include <iostream>
#include<queue>
using namespace std;
typedef struct BitNode {char data;BitNode* lchild, * rchild;
}BitNode, * BitTree;
void CreatTree(BitTree& T) {char ch;cin >> ch;if (ch == '/0') { return; }if (ch == '0') { T = NULL; }else {T = new BitNode;T->data = ch;/*先左后右保存数据**/CreatTree(T->lchild);CreatTree(T->rchild);}
}
// 层序遍历
void LevelOrder(BitTree t) {queue<BitNode*> q;//结点指针BitNode* p = t;	q.push(t);while (!q.empty()) {p = q.front();q.pop();cout << p->data << endl;if (p->lchild) {q.push(p->lchild);}if (p->rchild) {q.push(p->rchild);}}
}
//前序遍历
void PreOrder(BitNode* t) {if (t) {cout << t->data;PreOrder(t->lchild);PreOrder(t->rchild);}
}
//中序遍历
void InOrder(BitNode *t) {if (t) {InOrder(t->lchild);cout << t->data;InOrder(t->rchild);}
}
//后序遍历
void PostOrder(BitNode* t) {if (t) {PostOrder(t->lchild);PostOrder(t->rchild);cout << t->data;}
}
//获取树的高度
int getheight(BitNode *p){if(p==NULL)return 0;int left = getheight(p->lchild);int right = getheight(p->rchild);return max(left,right)+1;
}
//非递归后序遍历
void PostOrderTraverse()
{stack<Binary_tree_node*> s1; // 栈s1用于存储树节点stack<int> s2; // 栈s2用于标记节点是否已经被访问过(0表示未访问,1表示已访问)Binary_tree_node* p = root; // p指向树的根节点do{// 当p不为NULL时,遍历左子树while (p != NULL) {s1.push(p);        // 将当前节点压入s1栈s2.push(0);        // 在s2栈中压入0,表示该节点未访问过p = p->LeftChild;  // 移动到当前节点的左孩子if (s1.empty())    // 如果栈s1为空,表示树为空,跳出循环{break;}}// 如果p为NULL(意味着当前节点没有左孩子)时,开始处理节点if (!p == NULL)  // `!p`的条件使得该程序块在p为NULL时执行{if (s2.top() == 0)  // 如果s2栈顶为0,表示当前节点没有被访问过{s2.top() = 1;    // 将栈顶的0改为1,标记当前节点已访问过p = s1.top()->RightChild; // 转向当前节点的右孩子,准备遍历右子树}else if (s2.top() == 1)  // 如果s2栈顶为1,表示当前节点已访问过,且其左右子树都已处理{p = s1.top();    // 获取当前节点s1.pop();         // 从s1栈中弹出该节点s2.pop();         // 从s2栈中弹出对应的标记cout << p->data;  // 输出当前节点的值p = NULL;         // 将p置为NULL,表示当前节点已经处理完毕}}} while (!s1.empty()); // 当栈s1不为空时,继续遍历cout << endl; // 输出换行符
}

哈夫曼树编码与解码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<deque>
#define error -1
#define ok  1
using namespace std;
struct BitNode {BitNode* lchild;BitNode* rchild;int data;char ch;string str;
}*BitTree;
bool cmp(BitNode* a, BitNode* b) {return a->data < b->data;
}
//哈夫曼编码
void huffman(BitNode* t) {if (t->lchild) {t->lchild->str = t->str + '0';}if (t->rchild) {t->rchild->str = t->str + '1';}if (t->lchild)huffman(t->lchild);if (t->rchild)huffman(t->rchild);
}
//哈夫曼解码
int decode(string code, char txt[], BitNode* t) {int len = code.length();BitNode* curr = t;int index = 0;for (int i = 0; i < len; i++) {if (code[i] == '0') {curr = curr->lchild;}elsecurr = curr->rchild;if (!curr->lchild && !curr->rchild) {txt[index++] = curr->ch;curr = t;}}txt[index] = '\0'; // 确保字符串正确终止!!!if (curr != t)return error;else return ok;
}
int main() {int t;cin >> t;while (t--) {int n;cin >> n;deque<BitNode*>p;deque<BitNode*>q;for (int i = 0; i < n; i++) {BitNode* T = new BitNode();T->str = "";cin >> T->data;p.push_back(T);q.push_back(T);}for (int i = 0; i < n; i++) {cin >> p[i]->ch;}while (p.size()!=1) {sort(p.begin(), p.end(), cmp);BitNode* a = p.front(); p.pop_front();BitNode* b = p.front(); p.pop_front();BitNode* c = new BitNode();c->lchild = a;c->rchild = b;c->data = a->data + b->data;p.push_back(c);}BitNode* d = p.front();huffman(d);
//输出编码for (int i = 0; i < q.size(); i++) {cout << q[i]->data << "-" << q[i]->str << endl;}
//输出解码int m;cin >> m;while (m--) {string dcode;cin >> dcode;char txt[1000];decode(dcode, txt, d);if (decode(dcode, txt, d) == error)cout << "error" << endl;elsecout << txt << endl;}}return 0;
}

AVL平衡二叉树

#include <iostream>
using namespace std;
#define LH 1  // 左高
#define EH 0  // 等高
#define RH -1 // 右高
int max(int a, int b) {return a > b ? a : b;
}
class BiNode {
public:int key;      // 关键值int bf;       // 平衡因子BiNode* lChild, * rChild;BiNode(int kValue, int bValue = EH){key = kValue;bf = bValue;lChild = NULL;rChild = NULL;}
};
int getheight(BiNode* t) {if (t == NULL) {return 0;}return max(getheight(t->lChild), getheight(t->rChild)) + 1;
}
// 二叉排序树
class BST {
private:BiNode* root; // 根结点指针void rRotate(BiNode*& p);void lRotate(BiNode*& p);void leftBalance(BiNode*& t);void rightBalance(BiNode*& t);void insertAVL(BiNode*& t, int key); // 插入元素并做平衡处理void inOrder(BiNode* p);  // 中序遍历int countNodes(BiNode* p);  // 计算树中节点的数量
public:BST();void insertAVL(int key); // 二叉排序树插入元素~BST();void inOrder(); // 中序遍历void inOrderHelper(BiNode* p, int& currentNode, int totalNodes);
};
void BST::lRotate(BiNode*& p)//右旋 LL
{BiNode* q = p->lChild;p->lChild = q->rChild;q->rChild = p;p = q; // p变为新的根结点// 旋转后更新平衡因子p->bf = getheight(p->lChild) - getheight(p->rChild);p->rChild->bf = getheight(p->rChild->lChild) - getheight(p->rChild->rChild);
}
void BST::rRotate(BiNode*& p)//左旋 RR
{BiNode* q = p->rChild;p->rChild = q->lChild;q->lChild = p;p = q; // p变为新的根结点// 旋转后更新平衡因子p->bf = getheight(p->lChild) - getheight(p->rChild);p->lChild->bf = getheight(p->lChild->lChild) - getheight(p->lChild->rChild);
}
void BST::leftBalance(BiNode*& t)//左旋左孩子再右旋 LR
{rRotate(t->lChild);lRotate(t);
}
void BST::rightBalance(BiNode*& t)//右旋右孩子再左旋 RL
{lRotate(t->rChild);rRotate(t);
}
void BST::insertAVL(BiNode*& t, int key) {if (t == NULL) {t = new BiNode(key);return;}if (key < t->key) {insertAVL(t->lChild, key);if (getheight(t->lChild) - getheight(t->rChild) == 2) {if (key < t->lChild->key) {lRotate(t); // LL}else {leftBalance(t); // LR}}}else if (key > t->key) {insertAVL(t->rChild, key);if (getheight(t->rChild) - getheight(t->lChild) == 2) {if (key > t->rChild->key) {rRotate(t); // RR}else {rightBalance(t); // RL}}}// 更新平衡因子if (t != NULL) {t->bf = getheight(t->lChild) - getheight(t->rChild);}
}
// 中序遍历
void BST::inOrder(BiNode* p)
{if (p){inOrder(p->lChild);cout << p->key << ":" << p->bf;inOrder(p->rChild);}
}
int BST::countNodes(BiNode* p)
{if (p == NULL)return 0;return 1 + countNodes(p->lChild) + countNodes(p->rChild);
}
void BST::inOrder()
{int totalNodes = countNodes(root);  // 获取树中总节点数int currentNode = 0;  // 当前节点计数器// 中序遍历时判断是否为最后一个节点inOrderHelper(root, currentNode, totalNodes);cout << endl;  // 输出结束后换行
}
//消除最后一个节点及其平衡因子的空格
void BST::inOrderHelper(BiNode* p, int& currentNode, int totalNodes)
{if (p){inOrderHelper(p->lChild, currentNode, totalNodes);cout << p->key << ":" << p->bf;currentNode++;if (currentNode < totalNodes)cout << " ";  // 如果不是最后一个节点,输出空格inOrderHelper(p->rChild, currentNode, totalNodes);}
}
BST::BST()
{root = NULL;
}
BST::~BST()
{root = NULL;
}
void BST::insertAVL(int key)
{insertAVL(root, key);
}
int main(void)
{int t;cin >> t;while (t--){int n, elem;cin >> n;BST tree;while (n--){cin >> elem;tree.insertAVL(elem);}tree.inOrder();}return 0;
}

图的连通

#include <iostream>
using namespace std;void DFS(int** m, int n, int* visit, int temp)
{for (int j = 0; j < n; j++){if (m[temp][j] == 1 && visit[j] == 0){visit[j] = 1;DFS(m, n, visit, j);}}
}
void isconmected(int n)
{int** m;m = new int* [n];for (int i = 0; i < n; i++){m[i] = new int[n];for (int j = 0; j < n; j++)cin >> m[i][j];}int* visit = new int[n];for (int i = 0; i < n; i++)visit[i] = 0;int flag = 0;for (int i = 0; i < n; i++){visit[i] = 0;DFS(m, n, visit, i);        //对每个顶点都调用DFSfor (int j = 0; j < n; j++){if (visit[j] == 0)     //然后判断此顶点能否到达其它顶点,visit[j]=0代表不能到达{flag = 1;break;}elsevisit[j] = 0;}if (flag == 1)break;}if (flag == 0)cout << "Yes" << endl;elsecout << "No" << endl;delete[]m;
}
int main()
{int t;cin >> t;int n;while (t--){cin >> n;isconmected(n);}return 0;
}

图的广度遍历

#include <iostream>
#include <queue>
#include <cstring> // For memset
using namespace std;const int MAX = 20;class Map {
private:bool Visit[MAX];           // 访问标记数组int Matrix[MAX][MAX];      // 邻接矩阵int Vexnum;                // 顶点数void BFS(int v);           // 广度优先搜索public:void SetMatrix(int vnum, int mx[MAX][MAX]); // 设置邻接矩阵void BFSTraverse();       // 广度优先遍历图void ResetVisit();        // 重置访问标记数组
};// 设置邻接矩阵
void Map::SetMatrix(int vnum, int mx[MAX][MAX]) {Vexnum = vnum;// 清空矩阵memset(Matrix, 0, sizeof(Matrix));// 复制输入的邻接矩阵for (int i = 0; i < Vexnum; i++) {for (int j = 0; j < Vexnum; j++) {Matrix[i][j] = mx[i][j];}}
}// 广度优先遍历
void Map::BFSTraverse() {// 每次遍历前清空 Visit 数组ResetVisit();// 遍历所有未被访问的顶点for (int i = 0; i < Vexnum; i++) {if (!Visit[i]) {BFS(i);cout << endl;  // 每个 BFS 完成后换行}}
}// BFS 从顶点 v 开始进行广度优先搜索
void Map::BFS(int v) {queue<int> Q;         // 队列存储待访问的顶点Visit[v] = true;      // 标记当前顶点为已访问cout << v << " ";     // 打印当前顶点Q.push(v);            // 将当前顶点入队while (!Q.empty()) {int u = Q.front(); // 获取队头元素Q.pop();            // 出队// 遍历顶点 u 的所有邻接顶点for (int i = 0; i < Vexnum; i++) {if (Matrix[u][i] == 1 && !Visit[i]) {  // 如果 u 到 i 有边且 i 未被访问Visit[i] = true;                   // 标记 i 为已访问cout << i << " ";                  // 打印邻接点Q.push(i);                         // 将 i 入队}}}
}// 重置访问标记数组
void Map::ResetVisit() {memset(Visit, false, sizeof(Visit));  // 将 Visit 数组全部置为 false
}int main() {int t;cin >> t;  // 输入测试用例数量while (t--) {int n;cin >> n;  // 输入图的顶点数int ver[MAX][MAX];// 输入邻接矩阵for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {cin >> ver[i][j];}}Map a;a.SetMatrix(n, ver);  // 设置图的邻接矩阵a.BFSTraverse();      // 进行广度优先遍历}return 0;
}

图的深度遍历

#include<iostream>
using namespace std;
const int max_vertex_number = 20;
class Map {int vertex_number = 0;bool visited[max_vertex_number] = { false };int matrix[max_vertex_number][max_vertex_number];
public:Map() {cin >> vertex_number;for (int i = 0; i < vertex_number; i++)for (int j = 0; j < vertex_number; j++)cin >> matrix[i][j];}void DFS(int cur) {if (visited[cur])return;cout << cur << ' ';visited[cur] = true;for (int i = 0; i < vertex_number; i++)if (matrix[cur][i])DFS(i);}void Traverse() {for (int i = 0; i < vertex_number; i++)if (visited[i] == false)DFS(i);cout << endl;}
};
int main() {int t;cin >> t;while (t--) {Map test;test.Traverse();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SD下载、安装、使用、卸载-Stable Diffusion整合包v4.10发布!

目录 前言概述 SD安装1、安装软件2、启动3、配置4、运行5、测试 导入SD模型【决定画风】常用模型下载安装模型 SD卸载SD文生图提示词提示词使用技巧提示词的高级使用技巧强调关键词 前言 我向来不喜欢搞一些没有用的概念&#xff0c;所以直接整理可能用到的东西。 sd简单的说…

Mac iTerm2集成DeepSeek AI

1. 去deepseek官网申请api key&#xff0c;DeepSeek 2. 安装iTerm2 AI Plugin插件&#xff0c;https://iterm2.com/ai-plugin.html&#xff0c;插件解压后直接放到和iTerms相同的位置&#xff0c;默认就在/Applications 下 3. 配置iTerm2 4. 重启iTerm2,使用快捷键呼出AI对话…

MySQL数据库笔记——多版本并发控制MVCC

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;本文详细介绍MySQL的并发控制&#xff1a;多版本并发控制MVCC。 文章目录 背景介绍数据库并发控制——锁机制悲观锁和乐观锁悲观锁乐观锁 数据库并发控制——MVCC 的引入MVCC 和锁机…

电脑里msvcr120.dll文件丢失怎样修复?

电脑里msvcr120.dll文件丢失的修复指南 在电脑的日常使用中&#xff0c;我们可能会遇到各种各样的系统文件丢失问题&#xff0c;其中msvcr120.dll文件的丢失就是较为常见的一种。作为一名在软件开发领域深耕多年的从业者&#xff0c;我将为大家详细解析msvcr120.dll文件的重要…

今日头条ip属地根据什么显示?不准确怎么办

在今日头条这样的社交媒体平台上&#xff0c;用户的IP属地信息对于维护网络环境的健康与秩序至关重要。然而&#xff0c;不少用户发现自己的IP属地显示与实际位置不符&#xff0c;这引发了广泛的关注和讨论。本文将深入探讨今日头条IP属地的显示依据&#xff0c;并提供解决IP属…

【Rust自学】10.3. trait Pt.1:trait的定义、约束与实现

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 题外话&#xff1a;trait的概念非常非常非常重要&#xff01;&#xff01;&#xff01;整个第10章全都是Rust的重难点&#xff01;&#x…

大白话拆解——多线程中关于死锁的一切(七)(已完结)

前言&#xff1a; 25年初&#xff0c;这个时候好多小伙伴都在备战期末 小编明天还有一科考试&#xff0c;日更一篇&#xff0c;今天这篇一定会对小白非常有用的&#xff01;&#xff01;&#xff01; 因为我们会把案例到用代码实现的全过程思路呈现出来&#xff01;&#xff…

GitLab集成Runner详细版--及注意事项汇总【最佳实践】

一、背景 看到网上很多用户提出的runner问题其实实际都不是问题&#xff0c;不过是因为对runner的一些细节不清楚导致了误解。本文不系统性的介绍GitLab-Runner&#xff0c;因为这类文章写得好的特别多&#xff0c;本文只汇总一些常几的问题/注意事项。旨在让新手少弯路。 二、…

《数据结构》期末考试测试题【中】

《数据结构》期末考试测试题【中】 21.循环队列队空的判断条件为&#xff1f;22. 单链表的存储密度比1&#xff1f;23.单链表的那些操作的效率受链表长度的影响&#xff1f;24.顺序表中某元素的地址为&#xff1f;25.m叉树第K层的结点数为&#xff1f;26. 在双向循环链表某节点…

「Mac畅玩鸿蒙与硬件54」UI互动应用篇31 - 滑动解锁屏幕功能

本篇教程将实现滑动解锁屏幕功能&#xff0c;通过 Slider 组件实现滑动操作&#xff0c;学习事件监听、状态更新和交互逻辑的实现方法。 关键词 滑动解锁UI交互状态管理动态更新事件监听 一、功能说明 滑动解锁屏幕功能包含以下功能&#xff1a; 滑动解锁区域&#xff1a;用…

螺栓松动丢失腐蚀生锈检测数据集VOC+YOLO格式504张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;504 标注数量(xml文件个数)&#xff1a;504 标注数量(txt文件个数)&#xff1a;504 标注…

Postman测试big-event

报错500。看弹幕&#xff0c;知道可能是yml或sql有问题。 所以检查idea工作台&#xff0c; 直接找UserMapper检查&#xff0c;发现完全OK。 顺着这个error发现可能是sql有问题。因为提示是sql问题&#xff0c;而且是有now()的那个sql。 之后通过给的课件&#xff0c;复制课件…

如何使用大语言模型进行事件抽取与关系抽取

诸神缄默不语-个人CSDN博文目录 文章目录 1. 什么是事件抽取与关系抽取&#xff1f;2. 示例&#xff1a;使用大语言模型进行事件抽取与关系抽取 1. 什么是事件抽取与关系抽取&#xff1f; 事件抽取是指从文本中识别出与某些“事件”相关的信息。这些事件通常包括动作、参与者、…

NAT网络技术

NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是一种常用的网络技术&#xff0c;主要用于在私有网络和公共网络之间转换IP地址。在家庭和小型企业网络当中用的比较多。它的主要功能有IP地址重用和增强网络的安全性。   NAT允许一个整个网…

SpringBoot框架开发中常用的注解

文章目录 接收HTTP请求。RestController全局异常处理器Component依赖注入LombokDataBuildersneakyThrowsRequiredArgsConstructor 读取yml文件配置类注解 接收HTTP请求。 RequestMapping 接收HTTP请求。具体一点是 GetMapping PostMapping PutMapping DeleteMapping 一共…

TVS二极管选型【EMC】

TVS器件并联在电路中&#xff0c;当电路正常工作时&#xff0c;他处于截止状态&#xff08;高阻态&#xff09;&#xff0c;不影响线路正常工作&#xff0c;当线路处于异常过压并达到其击穿电压时&#xff0c;他迅速由高阻态变为低阻态&#xff0c;给瞬间电流提供一个低阻抗导通…

Azkaban其二,具体使用以及告警设置

目录 Azkaban的使用 1、使用Flow1.0(比较老旧&#xff09; 2、Flow2.0的用法 1、小试牛刀 2、YAML格式的数据 3、多任务依赖 4、内嵌流&#xff08;嵌套流&#xff09;案例 5、动态传参 3、Azkaban的报警机制 1&#xff09;邮箱通知 2&#xff09;电话报警机制 4、关…

文档 | Rstudio下的轻量级单页面markdown阅读器 markdownReader

需求&#xff1a;在写R数据分析项目的时候&#xff0c;代码及结果的关键变化怎么记录下来&#xff1f;最好git能很容易的跟踪版本变化。 markdown 是最理想的选择&#xff0c;本文给出一种Rstuidio下的轻量级md阅读器实现&#xff1a;markdownReader。书写md还是在Rstudio。更…

SonarQube相关的maven配置及使用

一、maven 全局配置 <settings><pluginGroups><pluginGroup>org.sonarsource.scanner.maven</pluginGroup></pluginGroups><profiles><profile><id>sonar</id><activation><activeByDefault>true</acti…

Arduino Uno简介与使用方法

目录 一、Arduino Uno概述 1. 硬件特性 2. 开发环境 二、Arduino Uno的基本使用方法 1. 硬件连接 2. 软件编程 三、Arduino Uno编程基础 1. 基本语法 2. 常用函数 四、Arduino Uno应用举例 1. LED闪烁 2. 温度检测 3. 超声波测距 五、Arduino Uno的扩展与应用 1…