链式存储结构的链表
| #include <iostream> |
| |
| using namespace std; |
| |
| typedef int Datatype; |
| |
| typedef struct LNode { |
| Datatype elem; |
| struct LNode * next; |
| }LNode, *LinkList; |
| |
| void InitList(LinkList &L) { |
| |
| L = new LNode; |
| L->next = NULL; |
| printf("单链表初始化成功!\n"); |
| } |
| |
| LNode* LocateElem(LinkList L, Datatype x) { |
| |
| LNode* p = L->next; |
| while(p != NULL && p->elem != x) |
| p = p->next; |
| return p; |
| } |
| |
| void ListInsert(LinkList &L, int i, Datatype e) { |
| LNode* p = L; |
| int j = 0; |
| while(p != NULL && j < i-1){ |
| p = p->next; |
| ++j; |
| } |
| if(p == NULL || j > i-1) { |
| puts("ERROR"); |
| } |
| else{ |
| LNode* s = new LNode; |
| s->elem = e; |
| s->next = p->next; |
| p->next = s; |
| puts("插入成功!"); |
| } |
| } |
| |
| void ListDelete (LinkList &L, int i) { |
| |
| LNode* p = L; |
| int j = 0; |
| while((p->next) && j < i-1){ |
| p = p->next; |
| ++j; |
| } |
| |
| if(!(p->next) || j > i-1) { |
| puts("删除失败,此位置不合理"); |
| } |
| else { |
| LNode* q = p->next; |
| p->next = q->next; |
| delete q; |
| puts("删除成功"); |
| } |
| } |
| |
| void LinkListDelete(LinkList &L) { |
| L->next = NULL; |
| delete L; |
| puts("删除成功!"); |
| } |
| |
| void showList (LinkList &L) { |
| LNode* p = L->next; |
| if(p == NULL) cout << "空"; |
| while(p != NULL) { |
| cout << p->elem << ' '; |
| p = p->next; |
| } |
| cout << endl; |
| } |
| |
| void MergeLiskList(LinkList &L1, LinkList &L2, LinkList &L3) { |
| LinkList t1 = L1->next, t2 = L2->next, p = L3; |
| |
| int cnt = 0; |
| while(t1 != NULL && t2 != NULL) { |
| LNode* s = new LNode; |
| if(t1->elem < t2->elem){ |
| s->elem = t1->elem; |
| t1 = t1->next; |
| } |
| else{ |
| s->elem = t2->elem; |
| t2 = t2->next; |
| } |
| p->next = s; |
| p = s; |
| cnt++; |
| } |
| while(t1 != NULL) { |
| cnt++; |
| LNode* s = new LNode; |
| s->elem = t1->elem; |
| p->next = s; |
| p = s; |
| t1 = t1->next; |
| } |
| while(t2 != NULL) { |
| cnt++; |
| LNode* s = new LNode; |
| s->elem = t2->elem; |
| p->next = s; |
| p = s; |
| t2 = t2->next; |
| } |
| } |
| |
| void showMenu() { |
| |
| printf("***********************************************\n"); |
| printf("***********************************************\n"); |
| printf("**** 请输入操作前面的数字,执行操作 *******\n"); |
| printf("****1.初始化一个单链表 *******\n"); |
| printf("****2.查找值为x的元素 *******\n"); |
| printf("****3.在第 i 个位置插入元素 *******\n"); |
| printf("****4.删除第i个元素 *******\n"); |
| printf("****5.删除单链表 *******\n"); |
| printf("****6.归并两个有序的单链表 *******\n"); |
| printf("****7.显示链表 *******\n"); |
| printf("****8.退出 *******\n"); |
| printf("***********************************************\n"); |
| printf("***********************************************\n"); |
| } |
| |
| int a[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; |
| |
| int main() { |
| showMenu(); |
| bool flag = true; |
| LinkList L1, L2,L3; |
| |
| cout << "L2"; InitList(L2); |
| cout << "操作之前请先初始化L1(即先执行操作1)" << endl; |
| LNode* p = L2; |
| for(int i = 0; i < 10; i++) { |
| LNode* q = new LNode; |
| q->elem = a[9-i]; |
| q->next = p->next; |
| p->next = q; |
| } |
| int i,x,e; |
| char c; |
| |
| while(flag) { |
| cout <<"请输入操作:" ; |
| int select; |
| cin >> select; |
| switch (select) |
| { |
| case 1 : InitList(L1); |
| break; |
| case 2 : |
| cout << "请输入一个元素的值:"; cin >> x; |
| p = LocateElem(L1, x); |
| if(p != NULL) cout << "该元素的地址为:" << p << endl; |
| else {cout << "未找到元素x" << endl; break;} |
| break; |
| case 3 : |
| cout << "请输入要插入的位置:"; cin >> i; |
| cout << "请输入要插入的元素值:"; cin >> e; |
| ListInsert(L1, i, e); |
| break; |
| case 4 : |
| cout << "请输入要删除元素的位置:"; cin >> i; |
| ListDelete(L1, i); |
| break; |
| case 5 : |
| cout << "确定要删除链表吗?(y/n): "; cin >> c; |
| if(c == 'Y' || c == 'y') LinkListDelete(L1); |
| break; |
| case 6 : |
| InitList(L3); |
| MergeLiskList(L1, L2, L3); |
| cout << "归并后的链表为:"; |
| showList(L3); |
| break; |
| case 7 : |
| cout << "当前链表为:"; |
| showList(L1); |
| break; |
| default: flag = false; |
| break; |
| } |
| } |
| |
| return 0; |
| } |
| |
顺序结构下的栈
| #include <iostream> |
| #include <stdio.h> |
| #define MAXQSIZE 100 |
| |
| using namespace std; |
| |
| typedef int SElemType; |
| |
| typedef struct { |
| SElemType *base; |
| SElemType *top; |
| int stacksize; |
| }SqStack; |
| |
| void InitStack(SqStack &S) { |
| S.base = new SElemType[MAXQSIZE]; |
| if(!S.base) { |
| cout << "空间分配失败!" << endl; |
| return ; |
| } |
| S.top = S.base; |
| S.stacksize = MAXQSIZE; |
| cout << "初始化成功!" << endl; |
| } |
| |
| void Push(SqStack &S, SElemType e) { |
| if(S.top - S.base == S.stacksize) { |
| cout << "栈已满!" << endl; |
| return ; |
| } |
| *S.top++ = e; |
| cout << "入栈成功!" << endl; |
| } |
| |
| void Pop(SqStack &S, SElemType &e) { |
| if(S.top == S.base) { |
| cout << "栈为空,无法取出元素" << endl; |
| return ; |
| } |
| e = *--S.top; |
| cout << "取出栈顶元素为" << e << endl; |
| return ; |
| } |
| |
| SElemType GetTop(SqStack S) { |
| if(S.top != S.base) |
| return *(S.top - 1); |
| else cout << "空"; |
| } |
| |
| void showMenu() { |
| printf("************************************************\n"); |
| printf("******** 顺序结构下的栈 *********\n"); |
| printf("********1. 初始化一个栈 *********\n"); |
| printf("********2. 入栈 *********\n"); |
| printf("********3. 出栈 *********\n"); |
| printf("********4. 取栈顶元素 *********\n"); |
| printf("********0. 退出 *********\n"); |
| printf("************************************************\n"); |
| printf("************************************************\n"); |
| } |
| |
| int main() { |
| showMenu(); |
| int select, e; |
| SqStack S; |
| while(true) { |
| cout << "请输入一个操作:"; cin >> select; |
| switch(select) { |
| case 1 : InitStack(S); break; |
| case 2 : cout << "请输入入栈元素:"; cin >> e; |
| Push(S, e); break; |
| case 3 : Pop(S,e); break; |
| case 4 : cout << "当前栈顶元素为" << GetTop(S) << endl; break; |
| case 0 : return 0; |
| default: break; |
| } |
| } |
| } |
顺序结构的循环队列
| #include <iostream> |
| #include <stdio.h> |
| #define MAXQSIZE 100 |
| |
| using namespace std; |
| |
| typedef int QElemType; |
| |
| typedef struct { |
| QElemType *base; |
| int qfront; |
| int qrear; |
| }SqQueue; |
| |
| void InitQueue(SqQueue &Q){ |
| Q.base = new QElemType[MAXQSIZE]; |
| if(!Q.base) { |
| cout << "分配空间失败!" << endl; |
| return ; |
| } |
| Q.qfront = Q.qrear = 0; |
| cout << "ok" << endl; |
| } |
| |
| int QueueLength(SqQueue Q) { |
| return (Q.qrear - Q.qfront + MAXQSIZE) % MAXQSIZE; |
| } |
| |
| void EnQueue(SqQueue &Q, QElemType e) { |
| if((Q.qrear + 1) % MAXQSIZE == Q.qfront) { |
| cout << "队列已满!" << endl; |
| return ; |
| } |
| Q.base[Q.qrear] = e; |
| Q.qrear = (Q.qrear + 1) % MAXQSIZE; |
| cout <<"ok" << endl; |
| } |
| |
| void DeQueue(SqQueue &Q, QElemType &e) { |
| if(Q.qfront == Q.qrear) { |
| cout << "当前队列为空" << endl; |
| return ; |
| } |
| e = Q.base[Q.qfront]; |
| Q.qfront = (Q.qfront + 1) % MAXQSIZE; |
| cout << "ok" << endl; |
| } |
| |
| QElemType Gethead(SqQueue Q) { |
| if(Q.qfront == Q.qrear) { |
| cout << "kong" << endl; |
| return -1; |
| } |
| return Q.base[Q.qfront]; |
| } |
| |
| void destroyQueue(SqQueue &Q) { |
| delete Q.base; |
| cout << "ok" << endl; |
| } |
| |
| void showMenu() { |
| printf("******************************************************\n"); |
| printf("******************************************************\n"); |
| printf("************* 顺序表实现循环队列 *****************\n"); |
| printf("*****1. 初始化队列 ****************\n"); |
| printf("*****2. 求队列长度 ****************\n"); |
| printf("*****3. 入队 ****************\n"); |
| printf("*****4. 出队 ****************\n"); |
| printf("*****5. 取队头元素 ****************\n"); |
| printf("*****6. 销毁队列 ****************\n"); |
| printf("******************************************************\n"); |
| printf("******************************************************\n"); |
| } |
| |
| int main() |
| { |
| SqQueue Q; |
| int select, e; |
| showMenu(); |
| while(true) { |
| cout << "请输入操作:" << endl; |
| cin >> select; |
| switch(select) { |
| case 1 :InitQueue(Q); |
| break; |
| case 2 : cout << "队列长度为" << QueueLength(Q) << endl; |
| break; |
| case 3 : cout << "请输入要入队的元素:"; cin >> e; |
| EnQueue(Q, e); break; |
| case 4 : DeQueue(Q, e); cout << "取出队头元素为:" << e << endl; |
| break; |
| case 5 : cout << "当前队头为:" << Gethead(Q) << endl; |
| break; |
| case 6 : destroyQueue(Q); |
| break; |
| default : |
| cout << "请输入有效操作" << endl; |
| break; |
| } |
| } |
| |
| return 0; |
| } |
链式存储结构实现队列
| #include <iostream> |
| |
| using namespace std; |
| |
| typedef int QElemtype; |
| |
| typedef struct QNode { |
| QElemtype data; |
| struct QNode * next; |
| }QNode, *QueuePtr; |
| |
| typedef struct { |
| QueuePtr qfront; |
| QueuePtr qrear; |
| }LinkQueue; |
| |
| void InitQueue (LinkQueue &Q){ |
| Q.qfront = Q.qrear = new QNode; |
| Q.qfront->next = NULL; |
| cout << "ok" << endl; |
| } |
| |
| void EnQueue(LinkQueue &Q, QElemtype e) { |
| QNode* p = new QNode(); |
| p->data = e; |
| p->next = NULL; |
| Q.qrear->next = p; |
| Q.qrear = p; |
| } |
| |
| void DeQueue(LinkQueue &Q, QElemtype &e) { |
| if(Q.qfront == Q.qrear) { |
| cout << "队列为空,无法取出元素!" << endl; |
| return ; |
| } |
| QNode* p = Q.qfront->next; |
| e = p->data; |
| Q.qfront->next = p->next; |
| if(Q.qrear == p) Q.qrear = Q.qfront; |
| delete p; |
| cout << "ok" << endl; |
| } |
| |
| QElemtype Gethead(LinkQueue Q) { |
| if(Q.qfront != Q.qrear) |
| return Q.qfront->next->data; |
| } |
| |
| int main() { |
| int select, e; |
| LinkQueue Q; |
| |
| while(true) { |
| cout << "请输入操作:";cin >> select; |
| switch(select) { |
| case 1 : InitQueue(Q); break; |
| case 2 : cout << "请输入入队元素:"; cin >> e; |
| EnQueue(Q, e); break; |
| case 3 : DeQueue(Q, e); |
| cout << "取出队头元素为" << e << endl; |
| break; |
| case 4 : cout << "当前队头元素为:" << Gethead(Q) << endl; |
| } |
| } |
| |
| return 0; |
| } |
| |
树
| #include <bits/stdc++.h> |
| |
| using namespace std; |
| |
| typedef char Element; |
| |
| typedef struct Node { |
| Element data; |
| struct Node * left; |
| struct Node * right; |
| }Node, *Nodeptr; |
| |
| int dis; |
| string s; |
| |
| Nodeptr addNode() { |
| if(dis == s.length() || s[dis] == '#') |
| return NULL; |
| Node *p = new Node; |
| p->data = s[dis]; |
| dis++; |
| p->left = addNode(); |
| dis++; |
| p->right = addNode(); |
| return p; |
| } |
| |
| Nodeptr CreateTree() { |
| Nodeptr p = new Node; |
| p = addNode(); |
| return p; |
| } |
| |
| void Pretraversal(Nodeptr node) { |
| cout << node->data << ' '; |
| if(node->left != NULL) |
| Pretraversal(node->left); |
| if(node->right != NULL) |
| Pretraversal(node->right); |
| } |
| |
| void Midtraversal(Nodeptr node) { |
| if(node->left != NULL) |
| Midtraversal(node->left); |
| cout << node->data << ' '; |
| if(node->right != NULL) |
| Midtraversal(node->right); |
| } |
| |
| void Lasttraversal(Nodeptr node) { |
| if(node->left != NULL) |
| Lasttraversal(node->left); |
| if(node->right != NULL) |
| Lasttraversal(node->right); |
| cout << node->data << ' '; |
| } |
| |
| void floortraversal(Nodeptr node) { |
| queue<Nodeptr> q; |
| q.push(node); |
| |
| while(q.size()) { |
| Nodeptr t = q.front(); |
| q.pop(); |
| cout << t->data << ' '; |
| if(t->left != NULL) q.push(t->left); |
| if(t->right != NULL) q.push(t->right); |
| } |
| } |
| |
| void Midtraversal2(Nodeptr node) { |
| stack<Nodeptr> st; |
| Nodeptr p = node, q; |
| |
| while(p != NULL || st.size()) { |
| if(p != NULL) { |
| st.push(p); |
| p = p->left; |
| } |
| else { |
| q = st.top(); |
| st.pop(); |
| cout << q->data << ' '; |
| p = q->right; |
| } |
| } |
| } |
| |
| int getDepth(Nodeptr node) { |
| if(node == NULL) return 0; |
| int l = getDepth(node->left); |
| int r = getDepth(node->right); |
| return max(l, r) + 1; |
| } |
| |
| int main() { |
| cin >> s; |
| Nodeptr npr = new Node; |
| npr = CreateTree(); |
| cout << "前序遍历:"; Pretraversal(npr); cout << endl; |
| cout << "中序遍历:"; Midtraversal(npr); cout << endl; |
| cout << "中序遍历2:"; Midtraversal2(npr); cout << endl; |
| cout << "后序遍历:"; Lasttraversal(npr);cout << endl; |
| cout << "层序遍历:"; floortraversal(npr); cout << endl; |
| cout << "深度:" << getDepth(npr) <<endl; |
| return 0; |
| } |
| |
| |
HuffmanTree的生成
| #include <iostream> |
| #include <map> |
| #include <cstdio> |
| #include <algorithm> |
| using namespace std; |
| |
| typedef struct { |
| int weight; |
| int parent, lchild, rchild; |
| }HTNode, *HuffmanTree; |
| |
| map<int, string> m1; |
| map<string, int> m2; |
| |
| void Select (HuffmanTree HT, int n, int &s1, int &s2) { |
| int w = 0x7fffffff; |
| for(int i = 1; i <= n; i++) { |
| if(w > HT[i].weight && HT[i].parent == 0){ |
| s1 = i; |
| w = HT[i].weight; |
| } |
| } |
| w = 0x7fffffff; |
| for(int i = 1; i <= n; i++) { |
| if(i != s1 && w > HT[i].weight && HT[i].parent == 0) { |
| s2 = i; |
| w = HT[i].weight; |
| } |
| } |
| } |
| |
| void PrintHT(HuffmanTree HT, int n) { |
| for(int i = 1; i < 2 * n; i++) |
| cout << HT[i].weight << ' ' << HT[i].parent << ' ' << HT[i].lchild << ' ' << HT[i].rchild << endl; |
| } |
| |
| void Init (HuffmanTree &HT, int n) { |
| HT = new HTNode[2 * n]; |
| for(int i = 1; i < 2 * n; i++) { |
| HT[i].weight = HT[i].parent = HT[i].lchild = HT[i].rchild = 0; |
| } |
| } |
| |
| void cindata (HuffmanTree &HT, int n) { |
| cout << "请输入权重:"; |
| for(int i = 1; i < 2 * n; i++) { |
| if(i <= n) { |
| cin >> HT[i].weight; |
| HT[i].parent = HT[i].lchild = HT[i].rchild = 0; |
| } |
| else HT[i].weight = HT[i].parent = HT[i].lchild = HT[i].rchild = 0; |
| } |
| } |
| |
| string getCode(HuffmanTree HT, int i, int n) { |
| string ans = ""; |
| while(i != 2 * n - 1) { |
| int p = HT[i].parent; |
| if(HT[p].lchild == i) ans += '0'; |
| else ans += '1'; |
| i = p; |
| } |
| reverse(ans.begin(), ans.end()); |
| return ans; |
| } |
| |
| void CreatHuffmanTree(HuffmanTree &HT, int n) { |
| if(n <= 1) return; |
| |
| |
| for(int i = n+1; i < 2 * n; i++) { |
| int s1 = 0, s2 = 0; |
| Select(HT, i-1, s1, s2); |
| HT[s1].parent = HT[s2].parent = i; |
| HT[i].lchild = s1, HT[i].rchild = s2; |
| HT[i].weight = HT[s1].weight + HT[s2].weight; |
| } |
| for(int i = 1; i <= n; i++) { |
| string s = getCode(HT, i, n); |
| m1[i] = s; |
| m2[s] = i; |
| } |
| } |
| |
| void Encoding(HuffmanTree HT, int n) { |
| |
| cout << "编码表" << endl; |
| for(int i = 1; i < n; i++) { |
| cout << char(i + 'a' - 1) << "--->" << m1[i] << endl; |
| } |
| cout << ' ' << "--->" << m1[n] << endl; |
| } |
| |
| void Translate() { |
| string s, tp; |
| cout << "请输入编码:"; cin >> s; |
| tp = ""; |
| cout << "此编码对应字符串为:"; |
| for(int i = 0; i < s.length(); i++) { |
| tp += s[i]; |
| if(m2.count(tp) != 0) { |
| if(m2[tp] != 27) cout << char(m2[tp] + 'a' - 1); |
| else cout << ' '; |
| tp = ""; |
| } |
| } |
| cout << endl; |
| } |
| |
| void Change() { |
| char c; |
| getchar(); |
| while(true) { |
| c = getchar(); |
| if(c == '\n') break; |
| if(c == ' ') cout << m1[27]; |
| else cout << m1[c-'a'+1]; |
| } |
| cout << endl; |
| } |
| |
| void showMenu() { |
| printf("**************************************************************\n"); |
| printf("*********1. 输入Huffman树的参数 ************\n"); |
| printf("*********2. 初始化Huffman的参数 ************\n"); |
| printf("*********3. 创建HuffmanTree和编码表 ************\n"); |
| printf("*********4. 输出编码表 ************\n"); |
| printf("*********5. 输入编码,并翻译为字符 ************\n"); |
| printf("*********6. 输入字符转换成编码 ************\n"); |
| printf("*********7. 退出 ************\n"); |
| printf("**************************************************************\n"); |
| } |
| |
| int main() |
| { |
| showMenu(); |
| int n; |
| HuffmanTree HT; |
| |
| while(true) { |
| int op; cout << "请输入操作:" ; cin >> op; |
| switch(op) { |
| case 1 : cindata(HT, n); break; |
| case 2 : |
| cout << "请输入需要编码字符的个数:"; cin >> n; |
| Init(HT, n); cout << "初始化成功!" << endl;break; |
| case 3 : CreatHuffmanTree(HT, n); cout << "创建成功!" << endl; break; |
| case 4 : Encoding(HT, n); break; |
| case 5 : Translate(); break; |
| case 6 : Change(); break; |
| case 7 : exit(0); |
| default: break; |
| } |
| } |
| |
| return 0; |
| } |
| |
| #include <iostream> |
| |
| #define MaxInt 32767 |
| #define MVNum 100 |
| |
| using namespace std; |
| |
| typedef char VertexType; |
| typedef int ArcType; |
| typedef struct { |
| VertexType vexs[MVNum]; |
| ArcType arcs[MVNum][MVNum]; |
| int vexnum, arcnum; |
| }AMGraph; |
| |
| int LocateVex(AMGraph G, VertexType v) { |
| int idx = 0; |
| while(G.vexs[idx] != v) idx++; |
| return idx; |
| } |
| |
| void CreateUDN(AMGraph &G) { |
| cout << "请输入顶点数、边数:"; |
| cin >> G.vexnum >> G.arcnum; |
| cout << "请输入"<< G.vexnum <<"个顶点:"; |
| for(int i = 0; i < G.vexnum; i++) cin >> G.vexs[i]; |
| for(int i = 0; i < G.vexnum; i++) |
| for(int j = 0; j < G.vexnum; j++) |
| G.arcs[i][j] = MaxInt; |
| cout << "请输入"<< G.arcnum <<"条边(格式:顶点 顶点 权重):" << endl; |
| for(int i = 0; i < G.arcnum; i++){ |
| ArcType w; |
| VertexType v1, v2; |
| cin >> v1 >> v2 >> w; |
| int a, b; |
| a = LocateVex(G, v1), b = LocateVex(G, v2); |
| G.arcs[a][b] = G.arcs[b][a] = w; |
| } |
| cout << "创建成功!" << endl; |
| } |
| |
| typedef int OtherInfo; |
| |
| typedef struct ArcNode{ |
| int adjvex; |
| struct ArcNode* nextarc; |
| OtherInfo info; |
| }ArcNode; |
| |
| typedef struct VNode { |
| VertexType data; |
| ArcNode *firstarc; |
| }VNode, AdjList[MVNum]; |
| |
| typedef struct { |
| AdjList vertices; |
| int vexnum, arcnum; |
| }ALGraph; |
| |
| int LocateVex2(ALGraph G, VertexType v) { |
| int idx = 0; |
| while(G.vertices[idx].data != v) idx++; |
| return idx; |
| } |
| |
| void CreateUDG(ALGraph &G) { |
| |
| cout << "请输入顶点数、边数:"; |
| cin >> G.vexnum >> G.arcnum; |
| cout << "请输入"<< G.vexnum <<"个顶点:"; |
| for(int i = 0; i < G.vexnum; i++) { |
| cin >> G.vertices[i].data; |
| G.vertices[i].firstarc = NULL; |
| } |
| cout << "请输入"<< G.arcnum <<"条边(格式:顶点 顶点 权重):" << endl; |
| for(int i = 0; i < G.arcnum; i++) { |
| VertexType v1, v2; |
| OtherInfo info; |
| cin >> v1 >> v2 >> info; |
| int a, b; |
| a = LocateVex2(G, v1), b = LocateVex2(G, v2); |
| |
| ArcNode* p1 = new ArcNode; |
| p1->adjvex = b; |
| p1->info = info; |
| p1->nextarc = G.vertices[a].firstarc; |
| G.vertices[a].firstarc = p1; |
| |
| ArcNode* p2 = new ArcNode; |
| p2->adjvex = a; |
| p2->info = info; |
| p2->nextarc = G.vertices[b].firstarc; |
| G.vertices[a].firstarc = p2; |
| } |
| cout << "创建完成!" << endl; |
| } |
| |
| int main() |
| { |
| AMGraph am; ALGraph al; |
| |
| CreateUDG(al); |
| cout << "Hello world!" << endl; |
| return 0; |
| } |
| |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步