PHP接收$_POST表單值為字串或陣列時,對安全轉義的處理函式
阿新 • • 發佈:2020-11-24
一、連結串列(Linked List)介紹
連結串列是有序的列表,但是它在記憶體中式儲存如下
1) 連結串列是以節點的方式來儲存,是鏈式儲存 2) 每個節點包含 data 域, next 域:指向下一個節點. 3) 如圖:發現連結串列的各個節點不一定是連續儲存. 4) 連結串列分帶頭節點的連結串列和沒有頭節點的連結串列,根據實際的需求來確定
二、單鏈表
使用帶head頭的單向連結串列實現 原始碼:單鏈表1,思路
準備 1)首先定義node節點物件 2)採用SingleLinkedList進行管理 3)在SingleLinkedList中定義head節點為new Node(-1,"","") 遍歷 1)定義臨時節點temp=head.next 2)while(temp!= null){temp=temp.next}遍歷並在其中列印temp 新增 1)定義一個臨時節點temp記錄到最後的位置 2)while(temp.next != null){temp=temp.next}移動指標 3)設定temp.next=node(新增的節點) 刪除 1)定義臨時節點temp=head,定義boolean flag為標識是否尋找到需要刪除的節點 2)while(temp.next != null){temp=temp.next}移動指標,判斷temp.next.no=no(輸入的節點id)為刪除節點的前一個節點並修改flag為刪除3)判定 flag標識是否找到刪除節點,如果找到就執行temp.next=temp.next.next 修改 1)定義臨時節點temp=head,定義boolean flag為標識是否尋找到需要修改的節點 2)while(temp.next != null){temp=temp.next}移動指標,判斷temp.next.no==node.no(node為需要修改的節點)並修改flag為修改 3)判定 flag標識是否找到修改節點,如果找到就執行node.next=temp.next.next;temp.next=node
2,程式碼實現
/** * 新增節點View Code*/ public void add(Node node) { Node temp = head; while (true) { if (temp.next == null) { break; } temp = temp.next; } temp.next = node; } /** * 刪除節點 */ public void del(int no) { //臨時節點為需要刪除節點的前一個節點 Node temp = head; boolean flag = true; //標識是否已經尋找完畢 while (true) { //如果已經遍歷完畢 if (temp.next == null) { flag = false; break; } //找到需要刪除節點的上一個節點 if (temp.next.no == no) { break; } temp = temp.next; } if (!flag) { System.out.println("找不到需要刪除的節點!!!"); return; } //刪除對應的節點 temp.next = temp.next.next; } /** * 修改節點 */ public void update(Node node) { //臨時節點為需要修改節點的前一個節點 Node temp = head; //判斷是否在連結串列中找到對應的節點 boolean flag = true; while (true) { //沒有找到對應的節點 if (temp.next == null) { flag = false; break; } //找到對應的節點 if (temp.next.no == node.no) { break; } //後移 temp = temp.next; } if (!flag) { System.out.println("找不到需要修改的節點!!!"); return; } //修改 node.next = temp.next.next; temp.next = node; } /** * 遍歷單鏈表 */ public void list(){ //第一個節點 Node temp = head.next; while (true) { if (temp == null) { break; } System.out.println(temp); temp = temp.next; } }
3,單鏈表擴充套件(面試題)
思路
查詢單鏈表中的倒數第k個節點 1)獲取連結串列的長度(新方法),採用臨時變數count=0,定義臨時變數temp=head.next;while(temp!=null){count++;temp=temp.next},將最終的count返回 2)使用num=length-k(倒數第k個),定義temp=head.next,flag=true 3)while(temp!= null){temp=temp.next},將num--,當num==0時則break並且修改flag為找到對應節點 4)判斷flag如果為找到狀態,則直接返回當前的temp 反轉單鏈表(改變連結串列結構) 1)定義一個新的頭節點reverse,定義指標cur=head.next,定義臨時節點temp=null 2)while(cur!=null){cur=cur.next}指標後移,指標後移之前先賦值temp=cur,然後將temp插入到reverse頭節點和reverse.next節點之間 3)最後將原頭節點的下一個節點指向新頭節點的下一個節點,head.next = reverse.next 反向遍歷(不改變連結串列結構) 1)定義棧Stack,定義臨時節點temp=head.next 2)while(temp!=null){temp=temp.next}遍歷,並將每個temp都push到棧 3)遍歷棧,pop棧中的元素
程式碼
/** * 反向遍歷 */ public void reversePrint() { //定義棧作為儲存 Stack<Node> nodes = new Stack<>(); Node temp = head; while (true) { if (temp.next == null) { break; } nodes.push(temp.next); temp = temp.next; } while (!nodes.empty()) { System.out.println(nodes.pop()); } } /** * 反轉(改變結構) */ public void reverse(){ //定義一個新的頭節點 Node reverse = new Node(-1,"",""); //指標 Node cur = head.next; //臨時變數為當前節點 Node temp = null; while (true) { if (cur == null) { break; } //當前值為指標指向的值 temp = cur; //指標後移 cur = cur.next; //當前節點為 頭節點的下一個接待你 temp.next = reverse.next; //頭節點的下一個節點為當前接待你 reverse.next = temp; } //將原始頭節點下一個節點指向 新頭節點的下一個節點 head.next = reverse.next; } /** * 查詢單鏈表中的倒數第 k 個節點 */ public static Node getByNum(Node head,int num){ int k = getLength(head) - num; if (k < 0) { return new Node(-1,"k大於長度","-1"); } Node temp = head.next; //判斷是否找不到 boolean flag = false; while (true) { if (temp == null) { break; } if (k == 0) { flag = true; break; } k--; temp = temp.next; } if (!flag) { //越界了,k為負數 return new Node(-1,"k為負數","-1"); } return temp; } /** * 求單鏈表中有效節點的個數 */ public static int getLength(Node head){ int count = 0; Node temp = head.next; while (true) { if (temp == null) { break; } count++; temp = temp.next; } return count; }View Code
三、雙向連結串列
原始碼:雙向連結串列
1,思路
準備 1)首先定義node節點物件,存在next和pre兩個屬性 2)採用DoubleLinkedList進行管理 3)在DoubleLinkedList中定義head節點為new Node(-1,"","") 遍歷 1)定義臨時節點temp=head.next 2)while(temp!= null){temp=temp.next}遍歷並在其中列印temp 新增 1)定義一個臨時節點temp記錄到最後的位置 2)while(temp.next != null){temp=temp.next}移動指標 3)設定temp.next=node(新增的節點),node.pre=temp(雙向關聯) 刪除(自我刪除) 1)定義臨時節點temp=head.next(需要被刪除的節點),定義boolean flag為標識是否尋找到需要刪除的節點 2)while(temp!= null){temp=temp.next}移動指標,判斷temp.no=no(輸入的節點id)為刪除節點,temp.pre.next=temp.next,如果temp.next不為空則temp.next.pre=temp.pre,並修改flag為刪除 3)判定 flag標識是否找到刪除節點 修改 1)定義臨時節點temp=head.next,定義boolean flag為標識是否尋找到需要修改的節點 2)while(temp!= null){temp=temp.next}移動指標,判斷temp.no==node.no(node為需要修改的節點),修改temp的屬性(或者修改next,pre指向),並修改flag為修改,break 3)判定 flag標識是否找到修改節點,沒找到給出提示
2,程式碼
private DoubleNode head = new DoubleNode(-1, "", ""); /** * 刪除節點 */ public void delete(int no) { if (no <= 0) { System.out.println("刪除節點的no不規範!!!"); return; } DoubleNode temp = head.next; boolean flag = false; while (temp != null) { if (temp.no == no) { temp.pre.next = temp.next; if (temp.next != null) { temp.next.pre = temp.pre; } flag = true; } temp = temp.next; } if (!flag) { System.out.println("需要被刪除的節點不存在"); } } /** * 修改節點 */ public void update(DoubleNode node) { if (node == null || node.no <= 0) { System.out.println("被修改的節點不規範!!!"); return; } DoubleNode temp = head.next; boolean flag = false; while (temp != null) { if (temp.no == node.no) { temp.name = node.name; temp.nickname = node.nickname; /*node.next = temp.next; node.pre = temp.pre; temp.pre.next = node; if (temp.next != null) { temp.next.pre = node; }*/ flag = true; } temp = temp.next; } if (!flag) { System.out.println("找不到節點!!!"); } } /** * 新增節點 */ public void add(DoubleNode node) { DoubleNode temp = head; while (true) { if (temp.next == null) { break; } temp = temp.next; } temp.next = node; node.pre = temp; } /** * 遍歷節點 */ public void list() { DoubleNode temp = head.next; while (true) { if (temp == null) { break; } System.out.println(temp); temp = temp.next; } }View Code
四、環形連結串列(約瑟夫問題)
原始碼:環形連結串列
1,應用場景
Josephu 問題為: 設編號為 1, 2, … n 的 n 個人圍坐一圈, 約定編號為 k(1<=k<=n) 的人從 1 開始報數, 數到 m 的那個人出列, 它的下一位又從 1 開始報數, 數到 m 的那個人又出列, 依次類推, 直到所有人出列為止, 由此產生一個出隊編號的序列。
2,建立環形連結串列
思路
準備 1)提前建立CircleNode物件為定義的節點 2)定義CircleLinkedList為環形連結串列的管理類 3)在CircleLinkedList中定義CircleNode first = null,定義連結串列的第一個節點 新增 1)判定first==null,如果為空則是第一次新增,那麼first=node,並且node.next=first 2)如果first節點不為空,定義temp=first節點,while(temp.next!=first){temp=temp.next}遍歷後移至first節點的前一個節點。 3)將node節點加到temp節點後first節點前,temp.next=node並且node.next=first 遍歷 1)定義temp=first,先列印first節點 2)while(temp.next!=first){temp=temp.next}列印temp.next
程式碼
/** * 遍歷 */ public void show() { if (first == null) { System.out.println("當前連結串列為空連結串列!!!"); return; } CircleNode temp = first; System.out.printf("當前編號為%d\n", first.no); while (temp.next != first) { System.out.printf("當前編號為%d\n", temp.next.no); temp = temp.next; } } /** * 初始化環形佇列 */ public void init(int num) { if (num < 1) { System.out.println("初始化環形連結串列小於1,失敗!!!"); return; } for (int i = 1; i <= num; i++) { CircleNode circleNode = new CircleNode(i); add(circleNode); } } /** * 新增node */ public void add(CircleNode node) { if (node == null) { System.out.println("需要新增的節點不存在!!!"); return; } if (first == null) { first = node; node.next = first; } CircleNode temp = first; while (true) { if (temp.next == first) { break; } temp = temp.next; } temp.next = node; node.next = first; }View Code
3,出圈
思路
1)獲取環形連結串列的總長度 2)定義出圈的方法需要接收step步長和start開始位置 3)定義cur=first需要出圈的節點,定義pre=first出圈的前一個節點while(pre.next!=first){pre=pre.next} 4)for迴圈start次,同時移動cur=cur.next和pre=pre.next 5)while(cur.next!=cur){...cur=cur.next}移動cur指標。在while迴圈中增加for迴圈step-1次,每次將pre和cur都後移,那麼移動完成之後設定pre.next=cur.next這樣就會去除cur 6)留存的就是最後的cur
程式碼
/** * 出圈 * * @param step 步長 * @param start 開始的位置 */ public void out(int step, int start) { int length = getLength(); if (length < 1 || step < 1 || start > length) { System.out.println("引數不合規!"); return; } //定義需要出圈的節點 CircleNode cur = first; //需要出圈節點的前一個節點 CircleNode pre = first; while (pre.next != first) { pre = pre.next; } //開始的位置 for (int i = 0; i < start; i++) { pre = pre.next; cur = cur.next; } while (cur.next != cur) { for (int i = 0; i < step-1; i++) { pre = pre.next; cur = cur.next; } System.out.printf("出圈編號為:%d\n",cur.no); pre.next = cur.next; cur = cur.next; } System.out.printf("出圈編號為:%d\n",cur.no); } /** * 獲取環形連結串列的長度 */ public int getLength() { if (first == null) { return 0; } int count = 1; CircleNode temp = first; while (temp.next != first) { count++; temp = temp.next; } return count; }View Code