C语言数据结构之双向链表(LIST)的实现

C语言数据结构之双向链表(LIST)的实现

  • 与单向链表相比,双向链表数据结构中多出一个指向链表前一个节点的节点指针prev!!!

双向链表数据类型的定义

  • 双向链表的创建 list_new
  • 双向链表的释放 list_free
  • 尾部追加 list_append
  • 头部追加 list_prepend
  • 逐项操作 list_foreach
  • 测试函数,字符串尾部追加结果:AAA BBB CCC DDD EEE
  • 字符串头部追加结果:EEE DDD CCC BBB AAA

代码如下:

/* filename : list.c */
#include <stdio.h>
#include <stdlib.h>/**/
typedef void (*LSFunc) (void *data);/**/
typedef struct _ListNode ListNode;
struct _ListNode {void *data;ListNode *prev, *next;
};/**/
ListNode *
list_node_new (void *data)
{ListNode *node = (ListNode*) malloc (sizeof(ListNode));node->data = data;node->prev = NULL;node->next = NULL;return node;
}/**/
void
list_free (ListNode *node)
{ListNode *tmp = node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){ListNode *pnode = tmp->next;free (tmp);tmp = pnode;}
}/**/
ListNode *
list_append (ListNode *head, void *data)
{ListNode *tmp = head, *node;while (tmp->next != NULL)tmp = tmp->next;node = list_node_new (data);node->prev = tmp;tmp->next = node;return head;
}/**/
ListNode *
list_prepend (ListNode *head, void *data)
{ListNode *tmp = head, *node;while (tmp->prev != NULL)tmp = tmp->prev;node = list_node_new (data);node->next = tmp;tmp->prev = node;return node;
}/**/
void
list_foreach (ListNode *node, LSFunc lsfunc)
{ListNode *tmp = node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){lsfunc (tmp->data);tmp = tmp->next;}
}/* ---------------------------------------- *//**/
void
out_string (void *data)
{printf ("%s ", (char*)data);
}/**/
void
test_list_append (void)
{ListNode *ls;char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");list_free (ls);
}/**/
void
test_list_prepend (void)
{ListNode *ls;char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_prepend (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");list_free (ls);
}/**/
int
main (int argc, char *argv[])
{test_list_append ();test_list_prepend ();return 0;
}
/* --[<\|/>]-- */

编译运行,检查内存,情况如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE ]
[ EEE DDD CCC BBB AAA ]
songvm@ubuntu:~/works/xdn/loo$ valgrind --leak-check=yes ./list
==3688== Memcheck, a memory error detector
==3688== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3688== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3688== Command: ./list
==3688== 
[ AAA BBB CCC DDD EEE ]
[ EEE DDD CCC BBB AAA ]
==3688== 
==3688== HEAP SUMMARY:
==3688==     in use at exit: 0 bytes in 0 blocks
==3688==   total heap usage: 11 allocs, 11 frees, 1,264 bytes allocated
==3688== 
==3688== All heap blocks were freed -- no leaks are possible
==3688== 
==3688== For counts of detected and suppressed errors, rerun with: -v
==3688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/loo$ 

双向链表求长度LENGTH 插入INSERT

  • 双向链表求长度 list_length
  • 双向链表插入节点 list_insert

代码如下:

/**/
int
list_length (ListNode *head)
{int len = 0;ListNode *tmp = head;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){tmp = tmp->next;len++;}return len;
}/**/
ListNode *
list_insert (ListNode *head, int nth, void *data)
{int idx = 0;ListNode *tmp = head;//, *node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){idx = idx + 1;if (idx == nth){ListNode *node = list_node_new (data);node->next = tmp->next;node->prev = tmp;tmp->next = node;break;}tmp = tmp->next; }return head;
}
  • 测试函数,创建双向链表AAA BBB CCC DDD EEE,在第3个索引处插入XXXX,目标结果AAA BBB CCC XXXX DDD EEE

代码如下:

/**/
void
test_list_insert (void)
{ListNode *ls;char *buf[6] = {"AAA", "BBB", "CCC", "DDD", "EEE", "XXXX"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");printf ("List length is %d\n", list_length (ls));ls = list_insert (ls, 3, buf[5]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");printf ("List length is %d\n", list_length (ls));list_free (ls);
}

编译运行,结果如预期,输出如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE ]
List length is 5
[ AAA BBB CCC XXXX DDD EEE ]
List length is 6
songvm@ubuntu:~/works/xdn/loo$ 

双向链表的连接concat

  • 双向链表连接函数list_concat,将两个双向链表连接成为一个双向链表

代码如下:

/**/
ListNode*
list_concat (ListNode *lsa, ListNode *lsb)
{ListNode *tmp = lsa, *node = lsb;while (tmp->next != NULL)tmp = tmp->next;while (node->prev != NULL)node = node->prev;tmp->next = node;node->prev = tmp;while (tmp->prev != NULL)tmp = tmp->prev;return tmp;
}
  • 测试将两个链表内容为:AAA BBB CCC DDD和XXX YYY ZZZ KKK,连接成为一个链表

代码如下:

/**/
void
test_list_concat (void)
{char *bufa[4] = {"AAA", "BBB", "CCC", "DDD"};char *bufb[4] = {"XXX", "YYY", "ZZZ", "KKK"};ListNode *lna, *lnb, *lnx;lna = list_node_new (bufa[0]);for (int i = 1; i < 4; i++)lna = list_append (lna, bufa[i]);printf ("[ ");list_foreach (lna, out_string);printf ("]\n");lnb = list_node_new (bufb[0]);for (int i = 1; i < 4; i++)lnb = list_append (lnb, bufb[i]);printf ("[ ");list_foreach (lnb, out_string);printf ("]\n");lnx = list_concat (lna, lnb);printf ("[ ");list_foreach (lnx, out_string);printf ("]\n");list_free (lnx);
}

编译运行,检查内存,结果如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD ]
[ XXX YYY ZZZ KKK ]
[ AAA BBB CCC DDD XXX YYY ZZZ KKK ]
songvm@ubuntu:~/works/xdn/loo$ valgrind --leak-check=yes ./list
==2951== Memcheck, a memory error detector
==2951== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2951== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2951== Command: ./list
==2951== 
[ AAA BBB CCC DDD ]
[ XXX YYY ZZZ KKK ]
[ AAA BBB CCC DDD XXX YYY ZZZ KKK ]
==2951== 
==2951== HEAP SUMMARY:
==2951==     in use at exit: 0 bytes in 0 blocks
==2951==   total heap usage: 9 allocs, 9 frees, 1,216 bytes allocated
==2951== 
==2951== All heap blocks were freed -- no leaks are possible
==2951== 
==2951== For counts of detected and suppressed errors, rerun with: -v
==2951== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/loo$ 

双向链表倒转REVERSE 取链表头节点FIRST 取链表尾节点LAST

  • 双向链表倒转 list_reverse
  • 取链表头节点 list_first
  • 取链表尾节点 list_last

代码如下:

/* list reverse tail to head */
ListNode*
list_reverse (ListNode *ls)
{ListNode *tmp = ls, *node = NULL;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){ListNode *pn = tmp;tmp = tmp->next;pn->next = node;pn->prev = NULL;if (node != NULL)node->prev = pn;node = pn;}return node;
}/* get list first node */
ListNode*
list_first (ListNode *ls)
{ListNode *tmp = ls;while (tmp->prev != NULL)tmp = tmp->prev;return tmp;
}/* get list last node */
ListNode*
list_last (ListNode *ls)
{ListNode *tmp = ls;while (tmp->next != NULL)tmp = tmp->next;return tmp;
}
  • 测试函数,创建链表字符串AAA到HHH,倒转输出内容,再由尾部向前依次输出内容

代码如下:

/**/
void
test_list_reverse (void)
{char *buf[8] = {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH"};ListNode *ls;ls = list_node_new (buf[0]);for (int i = 1; i < 8; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");ls = list_reverse (ls);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");{ListNode *tmp = ls;while (tmp->next != NULL)tmp = tmp->next;printf ("[ ");while (tmp != NULL){printf ("%s ", (char*)(tmp->data));tmp = tmp->prev;}printf ("]\n");}list_free (ls);
}

编译运行,达到预期,效果如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE FFF GGG HHH ]
[ HHH GGG FFF EEE DDD CCC BBB AAA ]
[ AAA BBB CCC DDD EEE FFF GGG HHH ]
songvm@ubuntu:~/works/xdn/loo$ 

双向链表删除指定节点 REMOVE_NTH

  • 双向链表删除指定节点 list_remove_nth

代码如下:

/**/
ListNode*
list_remove_nth (ListNode *ls, int nth)
{int idx = 0;ListNode *tmp = ls, *pn = ls;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){if (idx == nth){if (idx == 0){ls = tmp->next;ls->prev = NULL;free (tmp);break;}pn->next = tmp->next;tmp->next->prev = pn;free (tmp);break;}idx = idx + 1;pn = tmp;tmp = tmp->next;}return ls;
}
  • 测试函数,创建链表,删除第1第2节点,输出链表内容

代码如下:

/**/
void
test_list_remove (void)
{char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};ListNode *ls;ls = list_node_new (txt[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, txt[i]);list_foreach (ls, out_string); printf ("\n");ls = list_remove_nth (ls, 1);ls = list_remove_nth (ls, 2);list_foreach (ls, out_string); printf ("\n");list_free (ls);
}

编译运行,达到预期,效果如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
AAAA BBBB CCCC DDDD EEEE 
AAAA CCCC EEEE 
songvm@ubuntu:~/works/xdn/loo$ 

判断链表是否为循环链表

判断链表是否为循环链表is_round

代码如下:

/* if list is a round return 1 else return 0 */
int
list_isround (ListNode *ls)
{ListNode *tmp = ls;while (tmp != NULL){ListNode *node = tmp->next;if (ls == node) return 1;tmp = node;}return 0;
}
  • 测试函数,创建链表,取尾节点,尾节点next指针指向头节点,头节点的prev指针指向尾节点,形成循环链表

代码如下:

/**/
void
test_list_round (void)
{char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};ListNode *head, *tail;head = list_node_new (txt[0]);for (int i = 1; i < 5; i++)head = list_append (head, txt[i]);tail = list_last (head);tail->next = head; //link roundhead->prev = tail; //link roundif (list_isround (head))printf ("Double list is round!\n");elseprintf ("Double list not round!\n");tail->next = NULL; //cut roundhead->prev = NULL; //cut roundif (list_isround (head))printf ("Double list is round!\n");elseprintf ("Double list not round!\n");list_free (head);
}

编译运行,达到预期效果,输出如下:

songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
Double list is round!
Double list not round!
songvm@ubuntu:~/works/xdn/loo$ 

完整代码如下:

/* filename : list.c */
#include <stdio.h>
#include <stdlib.h>/* compile : gcc list.c -o list */
/*     run : ./list             *//* define function pointer for list foreach */
typedef void (*LSFunc) (void *data);/* define ListNode datatype */
typedef struct _ListNode ListNode;
struct _ListNode {void *data;ListNode *prev, *next;
};/* create a ListNode with data */
ListNode *
list_node_new (void *data)
{ListNode *node = (ListNode*) malloc (sizeof(ListNode));node->data = data;node->prev = NULL;node->next = NULL;return node;
}/* free a list, from head to tail every node */
void
list_free (ListNode *node)
{ListNode *tmp = node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){ListNode *pnode = tmp->next;free (tmp);tmp = pnode;}
}/* append a ListNode with data to head */
ListNode *
list_append (ListNode *head, void *data)
{ListNode *tmp = head, *node;while (tmp->next != NULL)tmp = tmp->next;node = list_node_new (data);node->prev = tmp;tmp->next = node;return head;
}/* prev append a ListNode with data to head */
ListNode *
list_prepend (ListNode *head, void *data)
{ListNode *tmp = head, *node;while (tmp->prev != NULL)tmp = tmp->prev;node = list_node_new (data);node->next = tmp;tmp->prev = node;return node;
}/* foreach listnode run lsfunc for data */
void
list_foreach (ListNode *node, LSFunc lsfunc)
{ListNode *tmp = node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){lsfunc (tmp->data);tmp = tmp->next;}
}/* get list length */
int
list_length (ListNode *head)
{int len = 0;ListNode *tmp = head;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){tmp = tmp->next;len++;}return len;
}/* insert a ListNode with data at nth in head */
ListNode *
list_insert (ListNode *head, int nth, void *data)
{int idx = 0;ListNode *tmp = head;//, *node;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){idx = idx + 1;if (idx == nth){ListNode *node = list_node_new (data);node->next = tmp->next;node->prev = tmp;tmp->next = node;break;}tmp = tmp->next; }return head;
}/* concat lsa and lsb and return a new ListNode pointer */
ListNode*
list_concat (ListNode *lsa, ListNode *lsb)
{ListNode *tmp = lsa, *node = lsb;while (tmp->next != NULL)tmp = tmp->next;while (node->prev != NULL)node = node->prev;tmp->next = node;node->prev = tmp;while (tmp->prev != NULL)tmp = tmp->prev;return tmp;
}/* list reverse tail to head */
ListNode*
list_reverse (ListNode *ls)
{ListNode *tmp = ls, *node = NULL;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){ListNode *pn = tmp;tmp = tmp->next;pn->next = node;pn->prev = NULL;if (node != NULL)node->prev = pn;node = pn;}return node;
}/* get list first node */
ListNode*
list_first (ListNode *ls)
{ListNode *tmp = ls;while (tmp->prev != NULL)tmp = tmp->prev;return tmp;
}/* get list last node */
ListNode*
list_last (ListNode *ls)
{ListNode *tmp = ls;while (tmp->next != NULL)tmp = tmp->next;return tmp;
}/**/
ListNode*
list_remove_nth (ListNode *ls, int nth)
{int idx = 0;ListNode *tmp = ls, *pn = ls;while (tmp->prev != NULL)tmp = tmp->prev;while (tmp != NULL){if (idx == nth){if (idx == 0){ls = tmp->next;ls->prev = NULL;free (tmp);break;}pn->next = tmp->next;tmp->next->prev = pn;free (tmp);break;}idx = idx + 1;pn = tmp;tmp = tmp->next;}return ls;
}/* if list is a round return 1 else return 0 */
int
list_isround (ListNode *ls)
{ListNode *tmp = ls;while (tmp != NULL){ListNode *node = tmp->next;if (ls == node) return 1;tmp = node;}return 0;
}/* ---------------------------------------- *//**/
void
out_string (void *data)
{printf ("%s ", (char*)data);
}/**/
void
test_list_append (void)
{ListNode *ls;char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");list_free (ls);
}/**/
void
test_list_prepend (void)
{ListNode *ls;char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_prepend (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");list_free (ls);
}/**/
void
test_list_insert (void)
{ListNode *ls;char *buf[6] = {"AAA", "BBB", "CCC", "DDD", "EEE", "XXXX"};ls = list_node_new (buf[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");printf ("List length is %d\n", list_length (ls));ls = list_insert (ls, 3, buf[5]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");printf ("List length is %d\n", list_length (ls));list_free (ls);
}/**/
void
test_list_concat (void)
{char *bufa[4] = {"AAA", "BBB", "CCC", "DDD"};char *bufb[4] = {"XXX", "YYY", "ZZZ", "KKK"};ListNode *lna, *lnb, *lnx;lna = list_node_new (bufa[0]);for (int i = 1; i < 4; i++)lna = list_append (lna, bufa[i]);printf ("[ ");list_foreach (lna, out_string);printf ("]\n");lnb = list_node_new (bufb[0]);for (int i = 1; i < 4; i++)lnb = list_append (lnb, bufb[i]);printf ("[ ");list_foreach (lnb, out_string);printf ("]\n");lnx = list_concat (lna, lnb);printf ("[ ");list_foreach (lnx, out_string);printf ("]\n");list_free (lnx);
}/**/
void
test_list_reverse (void)
{char *buf[8] = {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH"};ListNode *ls;ls = list_node_new (buf[0]);for (int i = 1; i < 8; i++)ls = list_append (ls, buf[i]);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");ls = list_reverse (ls);printf ("[ ");list_foreach (ls, out_string);printf ("]\n");{ListNode *tmp = ls;while (tmp->next != NULL)tmp = tmp->next;printf ("[ ");while (tmp != NULL){printf ("%s ", (char*)(tmp->data));tmp = tmp->prev;}printf ("]\n");}list_free (ls);
}/**/
void
test_list_remove (void)
{char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};ListNode *ls;ls = list_node_new (txt[0]);for (int i = 1; i < 5; i++)ls = list_append (ls, txt[i]);list_foreach (ls, out_string); printf ("\n");ls = list_remove_nth (ls, 1);ls = list_remove_nth (ls, 2);list_foreach (ls, out_string); printf ("\n");list_free (ls);
}/**/
void
test_list_round (void)
{char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};ListNode *head, *tail;head = list_node_new (txt[0]);for (int i = 1; i < 5; i++)head = list_append (head, txt[i]);tail = list_last (head);tail->next = head; //link roundhead->prev = tail; //link roundif (list_isround (head))printf ("Double list is round!\n");elseprintf ("Double list not round!\n");tail->next = NULL; //cut roundhead->prev = NULL; //cut roundif (list_isround (head))printf ("Double list is round!\n");elseprintf ("Double list not round!\n");list_free (head);
}/**/
int
main (int argc, char *argv[])
{//test_list_append ();//test_list_prepend ();//test_list_insert ();//test_list_concat ();//test_list_reverse ();//test_list_remove ();test_list_round ();return 0;
}
/* --[<\|/>]-- */

下一步研究栈(Stack)数据结构!!!

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

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

相关文章

整理一下实际开发和工作中Git工具的使用 (持续更新中)

介绍一下Git 在实际开发和工作中&#xff0c;Git工具的使用可以说是至关重要的&#xff0c;它不仅提高了团队协作的效率&#xff0c;还帮助开发者有效地管理代码版本。以下是对Git工具使用的扩展描述&#xff1a; 版本控制&#xff1a;Git能够跟踪代码的每一个修改记录&#x…

YOLO目标检测

文章目录 一、含义二、与传统检测对比1.one-stage的优缺点2.two-stage的优缺点 三、MAP指标1.基本概念2.计算方法3.指标意义 一、含义 YOLO&#xff08;You Only Look Once&#xff09;是一种基于深度学习的目标检测算法&#xff0c;由Joseph Redmon等人于2016年提出。它的核心…

力扣 困难 52.N皇后II

文章目录 题目介绍题解 题目介绍 题解 法一&#xff1a;返回51题N皇后List的长度 法二&#xff1a; class Solution {private int n, ans;private boolean[] onPath, diag1, diag2;public int totalNQueens(int n) {this.n n;onPath new boolean[n];diag1 new boolean[n * …

秃姐学AI系列之:语义分割 + 数据集 | 转置卷积 + 代码

语义分割 语义分割将图片中的每个像素分类到对应的类别 通常来说现在的会议软件的背景虚化这个功能用的就是语义分割技术 无人车进行路面识别也是语义分割技术 语义分割 vs 实例分割 语义分割将图像划分为若干组成区域&#xff0c;这类问题的方法通常利用图像中像素之间的相关…

1 -《本地部署开源大模型》如何选择合适的硬件配置

如何选择合适的硬件配置 为了在本地有效部署和使用开源大模型&#xff0c;深入理解硬件与软件的需求至关重要。在硬件需求方面&#xff0c;关键是配置一台或多台高性能的个人计算机系统或租用配备了先进GPU的在线服务器&#xff0c;确保有足够的内存和存储空间来处理大数据和复…

html+css+js实现Notification 通知

实现效果&#xff1a; 代码实现&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Notif…

【Linux】为什么环境变量具有全局性?共享?写时拷贝优化?

环境变量表具有全局性的原因&#xff1a; 环境变量表之所以具有全局性的特征&#xff0c;主要是因为它们是在进程上下文中维护的&#xff0c;并且在大多数操作系统中&#xff0c;当一个进程创建另一个进程&#xff08;即父进程创建子进程&#xff09;时&#xff0c;子进程会继承…

SAP 批量复制角色处理办法

SAP 批量复制角色处理办法 1. 定义2. 功能3. 应用场景4. 操作步骤5. 注意事项6.业务场景7.操作步骤(1)导出旧角色(2)导出文件数据修改(3)上传修改好的角色(4)生成角色参数文件(5) 调用函数批量创建角色(6)关于权限常用功能 SAP 批量复制角色&#xff08;Batch Role Copy&#x…

【系统规划与管理师】历年各章节分值汇总(论文)

【移动端浏览】☞【系统规划与管理师】历年各章节分值汇总&#xff08;论文&#xff09; 第4章 IT服务规划设计 第5章 IT服务部署实施 第6章 IT服务运营管理 第7章 IT服务持续改进 第8章 监督管理 第9章 IT服务营销 第10章 团队建设与管理

【二】企业级JavaScript开发之代码编辑器

代码编辑器 程序员接触时间最长的就是代码编辑器。 代码编辑器主要分两种&#xff1a;IDE&#xff08;集成开发环境&#xff09;和轻量编辑器。很多人喜欢这两种各选一个。 当然还有很多其他很好的编辑器&#xff0c;你可以选择一个你最喜欢的。 选择编辑器就像选择其他工具…

开源OpenStack

1.查询HCS基于OpenStack哪个版本开发 2.九大核心组件 OpenStack可以对接FC也可以对接KVM主机&#xff1b;&#xff08;OpenStack 对接华为FusionCompute&#xff0c;一个集群对应 openstack 一台计算主机&#xff09;-引申出nova compute 2.1nova nova两个核心组件nova contro…

马拉车算法(C/C++)

#1024程序员节 | 征文# 马拉车算法&#xff08;Manachers Algorithm&#xff09;是一种用于在字符串中查找最长回文子串的线性时间复杂度算法。该算法由Udi Manacher在1980年代提出&#xff0c;因此得名。它的核心思想是利用已知的回文信息来减少不必要的比较&#xff0c;从而提…

【Linux】-权限

&#x1f511;&#x1f511;博客主页&#xff1a;阿客不是客 &#x1f353;&#x1f353;系列专栏&#xff1a;深入代码世界&#xff0c;了解掌握 Linux 欢迎来到泊舟小课堂 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ​ 一、权限的概念 在Linux 中&…

软件测试与软件缺陷的基础知识

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

技术面没过,竟然是因为我没用过Pytest框架?

想象一下&#xff0c;你在一次技术面试中满怀信心&#xff0c;答完所有问题&#xff0c;结果却被告知没通过&#xff0c;原因竟然是——你没用过Pytest框架&#xff01;是的&#xff0c;在当今软件测试的世界里&#xff0c;Pytest已经成为了许多公司的“必备”技能。 那么问题…

数据库表的创建

运用的环境是pychram python3.11.4 创建一个表需要用到以下语法 注释已经写清楚各种语法的含义&#xff0c;记住缩进是你程序运行的关键&#xff0c;因为程序是看你的缩进来判断你的运行逻辑&#xff0c;像我这个就是缩进不合理导致的报错 那么今天分享就到这里&#xff0c;谢…

QScrollBar滑动条控件

人机验证简化版案例 //设置垂直滑动条的范围是0-100ui->verticalScrollBar->setRange(0,100);ui->horizontalScrollBar->setRange(0,100);//设置初始数值ui->verticalScrollBar->setValue(50);//void valueChanged(int value);connect(ui->verticalScroll…

uniapp修改input中placeholder样式

Uniapp官方提供了两种修改的属性方法&#xff0c;但经过测试&#xff0c;只有 placeholder-class 属性能够生效 <input placeholder"请输入手机验证码" placeholder-class"input-placeholder"/><!-- css --> <style lang"scss" s…

基于图像拼接开题报告

选题的背景与意义 在日常生活中&#xff0c;使用普通相机获取宽视野的场景图像时&#xff0c;必须通过调节相机的焦距才可以提取完整的场景。由于相机的分辨率有限&#xff0c;拍摄场景越大&#xff0c;得到的图像分辨率就越低&#xff0c;因此只能通过缩放相机镜头减小拍摄的…

VSCode按ctrl与鼠标左键无法实现跳转的解决办法

vscode编译环境老是出问题&#xff0c;下面介绍两种解决方法 需要提前配置好代码编译需要的库以及编译器位置等等。 ctrlshiftp,输入 >C/C配置&#xff08;JSON&#xff09; 打开生成的c_cpp_properties.json {"configurations": [{"name": "Li…