數據結構之LinkedList

系列文章目錄

數據結構之ArrayList-CSDN博客


目錄

系列文章目錄

前言

一、模擬實現鏈表

1. 遍歷鏈表

2. 插入節點

?3. 刪除節點

4. 清空鏈表

二、鏈表的常見操作

1. 反轉鏈表

2. 返回鏈表的中間節點

3. 鏈表倒數第 k 個節點

4. 合并兩個有序鏈表

5. 分割鏈表

6. 判斷鏈表是否回文

7. 找兩個鏈表的第一個公共節點

8. 判斷鏈表是否有環

9. 尋找鏈表入環的第一個節點

三、模擬實現雙向鏈表

1. 遍歷鏈表

2. 插入節點

3. 刪除節點

4. 清空鏈表

四、ArrayList 和 LinkedList 的區別


前言

本文通過單鏈表的模擬實現,幫助了解單鏈表的底層原理,以及常見的鏈表的常用操作,比如反轉鏈表,找鏈表的中間節點等。模擬實現雙向鏈表,了解雙向鏈表的底層原理,以及 ArrayList 和 LinkedList 的比較。


一、模擬實現鏈表

鏈表是物理存儲結構上非連續,邏輯上連續的存儲結構;每個節點都會保存下一個節點的哈希值,通過這個節點可以找到下一個節點;

鏈表的屬性:用 head 表示鏈表的頭節點;

public class MySingleList {static class ListNode{public int val;public ListNode next;public ListNode(int val){this.val = val;}}public ListNode head;// 鏈表的方法// ...
}

1. 遍歷鏈表

以下方法都需要遍歷一遍鏈表:

display(): void 打印節點信息;

size(): int 返回鏈表的長度;

contains(int key): boolean 判斷鏈表中是否包含 key;

    // 打印所有節點信息public void display(){ListNode cur = head;while(cur != null){System.out.print(cur.val + " ");cur = cur.next;}}// 求鏈表的長度public int size(){ListNode cur = head;int count = 0;while(cur != null){count++;cur = cur.next;}return count;}// 查找關鍵字 key 是否在鏈表中public boolean contains(int key){ListNode cur = head;while(cur != null){if(cur.val == key){return true;}cur = cur.next;}return false;}

2. 插入節點

addFirst(int data): void 頭插法,將節點插入到鏈表頭節點的位置;

addLast(int data): void 尾插法,將節點插入到鏈表尾節點的位置,尾插的時候要注意,當鏈表沒有節點,即 head == null,這時候要注意將要插入的節點設置為頭節點;

findIndexPrev(int index): ListNode 找到 index 位置節點的前驅;

addIndex(int index, int data): void 在 index 位置插入節點;

插入之前需要先判斷 index 位置是否合法;

如果合法再判斷一下是否是頭插,是否是尾插,因為這倆方法已經寫好了,可以調用;

找到要插入節點的前驅,找到前驅之后進行插入;

    // 頭插法public void addFirst(int data){ListNode node = new ListNode(data);node.next = head;head = node;}// 尾插法public void addLast(int data){ListNode node = new ListNode(data);ListNode cur = head;if(cur == null) {this.head = node;return;}while(cur.next != null){cur = cur.next;}cur.next = node;}// 在任意位置插入public void addIndex(int index, int data){if(index < 0 || index > size()){throw new PosOutOfBoundsException(index + "插入位置不合法");}if(index == 0){addFirst(data);return;}if(index == size()){addLast(data);return;}ListNode cur = findIndexPrev(index);ListNode node = new ListNode(data);node.next = cur.next;cur.next = node;}// 找到 index 下標的前一個節點private ListNode findIndexPrev(int index){ListNode cur = head;while(--index > 0){cur = cur.next;}return cur;}

?3. 刪除節點

remove(int key): void 刪除第一個值為 key? 的節點;

如果鏈表為空則直接返回;

如果頭節點為要刪除的節點,直接刪除;

如果要刪除的節點不存在,拋異常;

如果要刪除在后面,先找到要刪除節點的前驅,再刪除;

findPrev(int key): ListNode 找到值為 key 的節點的前驅,沒有要刪除的節點,返回 null;

removeAll(int key): void 刪除所有值為 key 的節點;

如果鏈表為空,直接返回;

從頭節點后面開始刪除,找到要刪除的節點和它的前驅,進行刪除;

刪除完成后,當前節點指針向后移動;

如果沒有找到要刪除的節點,前驅和當前節點指針都同步向后移動;

最后判斷頭節點,如果頭節點也是要刪除的節點,進行刪除;

    // 刪除節點public void remove(int key){if(head == null){return;}// 單獨刪除頭節點if(head.val == key){head = head.next;return;}ListNode prev = findPrev(key);if(prev == null){throw new RuntimeException("要刪除的節點不存在!");}ListNode del = prev.next;prev.next = del.next;}// 找到 data 節點的前驅private ListNode findPrev(int key){ListNode cur = head;while(cur.next != null){if(cur.next.val == key){return cur;}}return null;}// 刪除所有值為 key 的節點public void removeAll(int key){if(head == null){return;}ListNode prev = head;ListNode cur = prev.next;while(cur != null){if(cur.val == key){prev.next = cur.next;cur = cur.next;}else{prev = cur;cur = cur.next;}}// 判斷頭結點if(head.val == key){head = head.next;}}

4. 清空鏈表

clear(): void 清空鏈表,只需要將頭結點置空即可;

    // 清空鏈表public void clear(){this.head = null;}

二、鏈表的常見操作

1. 反轉鏈表

reverseList(ListNode head): ListNode 反轉鏈表;

如果鏈表為空,返回 null;

如果鏈表不為空,依次將 head 后面的元素進行頭插;

    public ListNode reverseList(ListNode head) {if(head == null) return head;ListNode cur = head.next;head.next = null;while(cur != null){ListNode next = cur.next;cur.next = head;head = cur;cur = next;}return head;}

2. 返回鏈表的中間節點

middleNode(ListNode head): ListNode 返回鏈表的中間節點,如果鏈表是奇數個元素,返回中間節點,如果鏈表是偶數個元素,返回右中點節點;

定義快慢指針,快指針每次走兩步,慢指針每次走一步,如果快指針走到最后一個位置或者空位置,返回慢指針指向的節點即可;

    public ListNode middleNode(ListNode head) {if(head == null){return head;}ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next;fast = fast.next;slow = slow.next;}return slow;}

3. 鏈表倒數第 k 個節點

findKthtoTail(ListNode head, int k): ListNode 找倒數第 k 個節點

先判斷 head 是否為空,如果 head 為空,返回 null;

再判斷 k 的值是否合法,如果不合法,返回 null;

定義快慢指針 fast 和 slow,先讓 fast 走 k - 1步,再讓 fast 和 slow 同時走, fast 走到尾巴節點的時候,slow 正好走到倒數第 k 個節點;?

    // 返回鏈表倒數第 k 個節點public ListNode findKthToTail(ListNode head, int k){if(head == null) return null;if(k <= 0 || k > size()) return null;ListNode fast = head;ListNode slow = head;while(--k > 0){fast = fast.next;}while(fast.next != null){fast = fast.next;slow = slow.next;}return slow;}

4. 合并兩個有序鏈表

mergeTwoLists(ListNode list1, ListNode list2): ListNode 合并兩個有序鏈表

兩個鏈表的元素相互比較,小的加入新的隊列,指針后移;

當有一個鏈表為空了,開始把剩下的鏈表的元素按順序加入到新的鏈表中;

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if(list1 == null) return list2;if(list2 == null) return list1;ListNode newHead = new ListNode();ListNode cur = newHead;while(list1 != null && list2 != null){if(list1.val <= list2.val){cur.next = list1;list1 = list1.next;}else{cur.next = list2;list2 = list2.next;}cur = cur.next;}while(list1 != null){cur.next = list1;list1 = list1.next;cur = cur.next;}while(list2 != null){cur.next = list2;list2 = list2.next;cur = cur.next;}return newHead.next;}

5. 分割鏈表

要求:將小于 x 的節點排在其余節點之前,不改變原來節點的順序;

partition(ListNode pHead, int x): ListNode 分割鏈表;

小于 x 的節點放 head1 后面,大于等于 x 的節點放在 head2 后面;

合并 head1 和 head2,返回新的鏈表;

注意:后面的鏈表的尾巴節點的 next 一定要置空,避免成環;

    public ListNode partition(ListNode pHead, int x) {if(pHead == null) return null;ListNode head1 = new ListNode(0);ListNode head2 = new ListNode(0);ListNode cur1 = head1;ListNode cur2 = head2;ListNode cur = pHead;while(cur != null){if(cur.val < x){cur1.next = cur;cur1 = cur1.next;}else{cur2.next = cur;cur2 = cur2.next;}cur = cur.next;}// 這是需要注意的地方cur2.next = null;cur1.next = head2.next;return head1.next;}

6. 判斷鏈表是否回文

chkPalindrom(ListNode A): boolean 檢查鏈表是否回文;

reverse(ListNode head): ListNode 反轉鏈表;

檢查鏈表是否回文的關鍵首先是找到鏈表中點(奇數個節點找中點,偶數個節點找右中點),找到中點后從這個節點開始,逆置鏈表,形成兩個鏈表;

分別從兩個鏈表的頭結點開始遍歷鏈表,如果值不同,直接返回 false,如果值相同繼續遍歷,直到遍歷完,返回 true;

    public boolean chkPalindrome(ListNode A) {if (A == null) return true;ListNode fast = A;ListNode slow = A;while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;}ListNode cur1 = A;ListNode cur2 = reverse(slow);boolean flag = true;while (cur1.next != null && cur2.next != null) {if (cur1.val != cur2.val) {flag = false;break;}cur1 = cur1.next;cur2 = cur2.next;}return flag;}public ListNode reverse(ListNode head) {ListNode newHead = new ListNode(0);ListNode cur = head;while (cur != null) {ListNode next = cur.next;cur.next = newHead.next;newHead.next = cur;cur = next;}return newHead.next;}

7. 找兩個鏈表的第一個公共節點

getIntersectionNode(ListNode headA, ListNode headB): ListNode 找兩個鏈表的第一個公共節點,沒有公共節點返回 null;

定義兩個指針遍歷兩個鏈表,同時讓兩個指針都往后走,如果相同返回節點即可;

如果不相同,當第一個指針遍歷到最后,就讓第一個指針指向第二個鏈表的頭結點;同理,第二個指針邊歷到最后,讓第二個指針也指向第一個鏈表;

這時候兩個指針都同時向后移動,如果兩個鏈表有公共節點,則一定會同時到達,因為兩個指針速度相同,相同時間走的路程也一定相同;

如果兩個鏈表沒有公共節點,則最終會同時指向 null,返回 null 即可;

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA == null || headB == null) return null;ListNode cur1 = headA;ListNode cur2 = headB;while(cur1 != cur2){if(cur1 != null) cur1 = cur1.next;else cur1 = headB;if(cur2 != null) cur2 = cur2.next;else cur2 = headA;}return cur1;}

8. 判斷鏈表是否有環

hasCycle(ListNode head): boolean 判斷鏈表是否有環;

定義一個 fast,一個 slow 指針,每次 fast 走兩步,slow 每次走一步,如果兩個指針相遇了,就證明有環,否則就沒有環;

    public boolean hasCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){return true;}}return false;}

9. 尋找鏈表入環的第一個節點

detectCycle(ListNode head): ListNode 尋找鏈表入環的第一個節點;

先找到 fast 和 slow 的相遇點,一個從起點出發,另一個從相遇點出發,最終兩個指針會在環的入口點相遇;

    public ListNode detectCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){break;}}if(fast == null || fast.next == null) return null;slow = head;while(fast != slow){fast = fast.next;slow = slow.next;}return fast;}

三、模擬實現雙向鏈表

雙向鏈表的屬性:用 head 表示鏈表的頭節點,last 表示鏈表的尾巴節點;

public class MyLinkedList {static class ListNode{private int val;private ListNode prev;private ListNode next;public ListNode(int data){this.val = data;}}public ListNode head;public ListNode last;
}

1. 遍歷鏈表

display(): void 打印鏈表;

size(): int 返回鏈表長度;

contains(int key): boolean 判斷鏈表中是否包含 key;

    // 打印鏈表public void display(){ListNode cur = head;while(cur != null){System.out.print(cur.val + " ");cur = cur.next;}System.out.println();}// 返回鏈表長度public int size(){ListNode cur = head;int count = 0;while(cur != null){count++;cur = cur.next;}return count;}// 判斷鏈表中是否包含 keypublic boolean contains(int key) {ListNode cur = head;while (cur != null) {if (cur.val == key) {return true;}cur = cur.next;}return false;}

2. 插入節點

addFirst(int data): void 頭插法,將節點插入到鏈表頭節點的位置;

注意:如果鏈表沒有節點,插入的時候要把頭指針和尾指針都指向插入的節點;

addLast(int data): void 尾插法,將節點插入到鏈表尾節點的位置,尾插的時候要

注意:如果鏈表沒有節點,插入的時候要把頭指針和尾指針都指向插入的節點;

findIndexPrev(int index): ListNode 找到 index 位置節點的前驅;

addIndex(int index, int data): void 在 index 位置插入節點;

插入之前需要先判斷 index 位置是否合法;

如果合法再判斷一下是否是頭插,是否是尾插,因為這倆方法已經寫好了,可以調用;

找到要插入節點的前驅和后繼,進行插入;

    // 頭插法public void addFirst(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {node.next = head;head.prev = node;head = node;}}// 尾插法public void addLast(int data){ListNode node = new ListNode(data);if(head == null){head = node;last = node;}else{last.next = node;node.prev = last;last = node;}}// 在 index 位置插入public void addIndex(int index, int data){if(index < 0 || index > size()){throw new RuntimeException(index + "位置不合法!");}if(index == 0){addFirst(data);return;}else if(index == size()){addLast(data);return;}ListNode node = new ListNode(data);ListNode prevNode = findPrev(index);ListNode nextNode = prevNode.next;prevNode.next = node;node.prev = prevNode;node.next = nextNode;nextNode.prev = node;}private ListNode findPrev(int index){ListNode cur = head;while(--index > 0){cur = cur.next;}return cur;}

3. 刪除節點

remove(int key): void 刪除第一個值為 key? 的節點;

找到要刪除節點的前驅和后繼;

如果前驅為空,就刪除頭節點,刪除頭結點要特殊處理只有一個節點的情況;

如果后繼為空,就刪除尾節點,刪除尾節點要特殊處理只有一個節點的情況;

如果刪除中間節點,刪除后返回;

removeAll(int key): void 刪除所有值為 key 的節點;

注意:原理同上,不同點是刪除一個節點后,繼續向后遍歷;

    // 刪除第一次出現關鍵字 key 的節點public void remove(int key){ListNode cur = head;while(cur != null){if(cur.val == key){ListNode prevNode = cur.prev;ListNode nextNode = cur.next;if(prevNode != null) {prevNode.next = nextNode;}else{head = head.next;if(head != null){head.prev = null;}}if(nextNode != null) {nextNode.prev = prevNode;}else{last = last.prev;if(last != null){last.next = null;}}break;}cur = cur.next;}}// 刪除所有值為 key 的節點public void removeAll(int key){ListNode cur = head;while(cur != null) {if (cur.val == key) {ListNode prevNode = cur.prev;ListNode nextNode = cur.next;if (prevNode != null) {prevNode.next = nextNode;} else {head = head.next;if(head != null){head.prev = null;}}if (nextNode != null) {nextNode.prev = prevNode;} else {last = last.prev;if(last != null){last.next = null;}}cur = nextNode;}else{cur = cur.next;}}}

4. 清空鏈表

clear(): void 清空鏈表;

注意:要把 headlast 置空;

    public void clear(){ListNode cur = head;while(cur != null){ListNode next = cur.next;cur = null;cur = next;}head = null;last = null;}

四、ArrayList 和 LinkedList 的區別

存儲上:

ArrayList 在存儲空間上是連續的,LinkedList 邏輯上是,連續的,在存儲空間上是不一定連續的;

操作上:

從查詢元素上來說,ArrayList 的時間復雜度是 O(1),而 LinkedList 不支持隨機訪問;

從插入上來說:

LinkedList 的時間復雜度是 O(1),ArrayList 頭插時間復雜度是 O(n),因為需要把把元素統一往后移一個位置;

ArrayList 在插入時,空間不夠時,需要擴容,而 LInkedList 沒有容量的概念;

應用場景:

ArrayList 適合頻繁查詢,LinkedList 適合頻繁插入刪除;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909183.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909183.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909183.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DC3靶機滲透

1. 靶機介紹 主要的內容有 sql 注入漏洞、joomla 框架漏洞、ssh 攻擊、shell 反彈、提權 信息收集(ip、端口、目錄、指紋信息)--->利用漏洞--->反彈---->提權 2. 信息收集 2.1. 掃描存活 ip 192.168.220.134 2.2. 端口掃描 nmap -T4 -A -p- 192.168.220.134 …

C# 線程交互

一、為什么要進行線程交互 在C#中&#xff0c;線程交互通常涉及到多個線程之間的數據共享和同步。?. 一、全局變量 在C#中&#xff0c;全局變量是指在程序的任何地方都可以訪問的變量。通常&#xff0c;全局變量是在類的外部定義的&#xff0c;或者在所有方法之外定義的。全…

Cursor 編輯器中的 Notepad 功能使用指南

Cursor 編輯器中的 Notepad 功能使用指南 摘要 本指南全面介紹了 Cursor 編輯器中的 Notepad 功能&#xff0c;涵蓋其用途、多種訪問方式、適用場景以及與其它功能的整合技巧等內容&#xff0c;助力用戶高效利用該功能提升工作流程效率。 不同訪問方式介紹 功能概述 Curso…

用于評估大語言模型(LLMs)能力的重要基準任務(Benchmark)

基準任務涵蓋了 多領域&#xff08;如語言理解、數學、推理、編程、醫學等&#xff09;和 多能力維度&#xff08;如事實檢索、計算、代碼生成、鏈式推理、多語言處理&#xff09;。常用于模型發布時的對比評測&#xff0c;例如 GPT-4、Claude、Gemini、Mistral 等模型的論文或…

力扣HOT100之技巧:169. 多數元素

這道題如果不考慮空間復雜度和時間復雜度的限制的話很好做&#xff0c;一種思路是通過一次遍歷將所有元素的數量記錄在一個哈希表中&#xff0c;然后我們直接返回出現次數最多的鍵即可。另一種思路是直接對數組進行排序&#xff0c;數組中間的值一定是多數元素&#xff0c;因為…

wordpress首頁調用指定ID頁面內的相冊

要在WordPress首頁調用ID為2的頁面中的相冊&#xff0c;你可以使用以下幾種方法&#xff1a; 方法一&#xff1a;使用短代碼和自定義查詢 首先&#xff0c;在你的主題的functions.php文件中添加以下代碼&#xff1a; function display_page_gallery($atts) {$atts shortcod…

基于深度學習的異常檢測系統:原理、實現與應用

前言 在現代數據驅動的業務環境中&#xff0c;異常檢測&#xff08;Anomaly Detection&#xff09;是一個關鍵任務&#xff0c;它能夠幫助企業和組織及時發現數據中的異常行為或事件&#xff0c;從而采取相應的措施。異常檢測廣泛應用于金融欺詐檢測、網絡安全、工業設備故障監…

Java基于BS架構的OA流程可視化實戰:從工作流引擎到前端交互(附完整源代碼+論文框架)

一、引言&#xff1a;BS架構OA系統的流程可視化需求 在企業信息化建設中&#xff0c;基于瀏覽器/服務器&#xff08;BS&#xff09;架構的OA系統通過流程自動化提升辦公效率&#xff0c;而流程可視化是實現流程監控、優化的核心模塊。本文基于Java技術棧&#xff0c;結合Activ…

JavaWeb-數據庫連接池

目錄 1.springboot默認Hikari(追光者)連接池 2.切換為Druid(德魯伊)連接池 1.springboot默認Hikari(追光者)連接池 2.切換為Druid(德魯伊)連接池 一般幾乎用不到&#xff0c;不需要切換 <!--Druid連接池--> <dependency><groupId>com.alibaba</groupId&…

c# 完成恩尼格瑪加密擴展

c# 完成恩尼格瑪加密擴展 恩尼格瑪擴展為可見字符恩尼格瑪的設備原始字符順序轉子的設置反射器的設置連接板的設置 初始數據的設置第一版 C# 代碼第二版 C# 代碼 總結 恩尼格瑪 在之前&#xff0c;我們使用 python 實現了一版恩尼格瑪的加密算法&#xff0c;但是這一版&#x…

【Redisson】鎖可重入原理

目錄 一、基本原理 二、源碼解析&#xff1a; &#xff08;2&#xff09;獲取鎖 &#xff08;1&#xff09;釋放鎖&#xff1a; 之前給大家介紹過redisson的分布式鎖&#xff0c;用redisson來實現比自己手搓簡單的分布式鎖有很多好處&#xff0c;因為這些可重入、可重試的邏…

BERT 模型微調與傳統機器學習的對比

BERT 微調與傳統機器學習的區別和聯系&#xff1a; 傳統機器學習流程 傳統機器學習處理文本分類通常包含以下步驟&#xff1a; 特征工程&#xff1a;手動設計特征&#xff08;如 TF-IDF、詞袋模型&#xff09;模型訓練&#xff1a;使用分類器&#xff08;如 SVM、隨機森林、邏…

(12)-Fiddler抓包-Fiddler設置IOS手機抓包

1.簡介 Fiddler不但能截獲各種瀏覽器發出的 HTTP 請求&#xff0c;也可以截獲各種智能手機發出的HTTP/ HTTPS 請求。 Fiddler 能捕獲Android 和 Windows Phone 等設備發出的 HTTP/HTTPS 請求。同理也可以截獲iOS設備發出的請求&#xff0c;比如 iPhone、iPad 和 MacBook 等蘋…

芯科科技Tech Talks技術培訓重磅回歸:賦能物聯網創新,共筑智能互聯未來

聚焦于Matter、藍牙、Wi-Fi、LPWAN、AI/ML五大熱門無線協議與技術 為年度盛會Works With大會賦能先行 隨著物聯網&#xff08;IoT&#xff09;和人工智能&#xff08;AI&#xff09;技術的飛速發展&#xff0c;越來越多的企業和個人開發者都非常關注最新的無線連接技術和應用…

docker-compose容器單機編排

docker-compose容器單機編排 開篇前言 隨著網站架構的升級&#xff0c;容器的使用也越來越頻繁&#xff0c;應用服務和容器之間的關系也越發的復雜。 這個就要求研發人員能更好的方法去管理數量較多的服務器&#xff0c;而不能手動挨個管理。 例如一個LNMP 架構&#xff0c;就…

LeetCode--29.兩數相除

解題思路&#xff1a; 1.獲取信息&#xff1a; 給定兩個整數&#xff0c;一個除數&#xff0c;一個被除數&#xff0c;要求返回商&#xff08;商取整數&#xff09; 限制條件&#xff1a;&#xff08;1&#xff09;不能使用乘法&#xff0c;除法和取余運算 &#xff08;2&#…

中山大學GaussianFusion:首個將高斯表示引入端到端自動駕駛多傳感器融合的新框架

摘要 近年來由于端到端自動駕駛極大簡化了原有傳統自動駕駛模塊化的流程&#xff0c;吸引了來自工業界和學術界的廣泛關注。然而&#xff0c;現有的端到端智駕算法通常采用單一傳感器&#xff0c;使其在處理復雜多樣和具有挑戰性的駕駛場景中受到了限制。而多傳感器融合可以很…

《哈希算法》題集

1、模板題集 滿足差值的數字對 2、課內題集 字符統計 字符串統計 優質數對 3、課后題集 2006 Equations k倍區間 可結合的元素對 滿足差值的數字對 異常頻率 神秘數對 費里的語言 連連看 本題集為作者&#xff08;英雄哪里出來&#xff09;在抖音的獨家課程《英雄C入門到精…

Cordova移動應用對云端服務器數據庫的跨域訪問

Cordova移動應用對云端服務器數據庫的跨域訪問 當基于類似 Cordova這樣的跨平臺開發框架進行移動應用的跨平臺開發時&#xff0c;往往需要訪問部署在公網云端服務器上的數據庫&#xff0c;這時就涉及到了跨域數據訪問的問題。 文章目錄 Cordova移動應用對云端服務器數據庫的跨…

mysql知識點3--創建和使用數據庫

mysql知識點3–創建數據庫 創建數據庫 在MySQL中創建數據庫使用CREATE DATABASE語句。語法如下&#xff1a; CREATE DATABASE database_name;其中database_name為自定義的數據庫名稱。例如創建名為test_db的數據庫&#xff1a; CREATE DATABASE test_db;可以添加字符集和排…