单链表的创建、删除、反转、插入、排序操作
單鏈表的創建、刪除、反轉、插入、排序操作
文章目錄
- 單鏈表的創建、刪除、反轉、插入、排序操作
- 1.1 鏈表引言
- 1.2 單鏈表節點的數據結構
- 1.3 創建鏈表
- 1.4 打印整個鏈表
- 1.5 鏈表插入數據
- 1.6 刪除某一個節點
- 1.7 刪除整個鏈表
- 1.8 鏈表的反轉
- 1.9 鏈表的排序
1.1 鏈表引言
? 在初學鏈表時很多人會問,什么是鏈表,鏈表怎么實現,原理是什么?的確帶著問題學習會讓你變得更快,鏈表可以簡單理解為老師領著幼兒園小朋友過馬路,他們手拉手牽著一起,老師在最前面領著后面的小朋友,老師就是這個領頭人(鏈表的頭節點),每一個小朋友可以看做一個節點。
1.2 單鏈表節點的數據結構
? 單鏈表的節點數據根據自己的需要自行設置,但是數據中必然存在一個指針,而且指針類型為本數據類型,本文為了展示出其相關操作的原理,因此節點的數據定義相對簡單。
/*鏈表的節點結構定義*/ typedef struct list_node {int data;struct list_node *next; }list_node;1.3 創建鏈表
? 創建鏈表需要自定義一個函數,指定鏈表頭,應該創建幾個節點,每個節點的數據自行輸入所以進行如下定義。使用whlie語句進行創建幾個節點的判斷,并且對每一個節點進行動態分配空間,通過scanf輸入數據。當知道有幾個小朋友需要連接老師(頭節點)時就很容易知道,老師的下一個牽手的應該是一個小朋友,而最后一個小朋友沒有東西牽著,所以為NULL。
int creat_list(list_node *head,int n) {if(head!=NULL&&n>0){list_node *p=head;int input_data;while(n>0){p->next=(list_node *)malloc(sizeof (list_node));printf("please input data:\n");scanf("%d",&input_data);p->next->data=input_data;p=p->next;n--;head->data++;}p->next=NULL;//鏈表的尾部節點下個指向為空,理解最后一個小朋友沒東西牽著return 0;}else{printf("輸入創建鏈表參數出錯:\n");return -1;} }1.4 打印整個鏈表
? 打印鏈表實現相對簡單,相當于老師牽著小朋友,讓每個小朋友進行報數,當到最后一個小朋友時牽著為空氣,報數完畢,所以判斷條件就是當下一個指針指向為空的時候停止遍歷鏈表。
/*打印整個鏈表*/ void print_list(list_node *head) {if(head!=NULL){printf("sum node %d\n",head->data);list_node *p=head->next;while(p!=NULL){printf("~~~~~~~~~~~%d\n",p->data);p=p->next;}} }1.5 鏈表插入數據
? 鏈表插入的函數,指定要插入的鏈表的頭節點,插入的位置,需要插入的數據。插入的原理如下圖:假設在1號和2號之間需要插入一個小朋友,首先應該報數,當一號報數完畢后,我們知道了應該在此插入,然后停下操作,先創建一個節點空間,然后把小朋友(節點數據)放進這個空間,新插入的小朋友應該是一邊被一號牽著,另一邊牽著2號。
/*第一個參數指定鏈表頭,第二參數在哪一個位置之后插入值*/ void insert_data(list_node *head,int data,int n) {if(n<0||head->data<n||head==NULL){printf("插入參數出錯\n");}else{list_node *p=head->next;list_node *pre=head;while(n>0)//此處相當于先報數{pre=p;p=p->next;n--;}list_node *new_node=(list_node *)malloc(sizeof (list_node));new_node->data=data;new_node->next=p; //此處對應紅色解釋圖pre->next=new_node;head->data++;} }1.6 刪除某一個節點
? 刪除某一個節點,也是需要知道鏈表的表頭,和刪除第幾個節點,原理和插入類似,如下圖所示:
void delete_data(list_node *head,int n) {if(n<=0||head==NULL){printf("輸入參數錯誤");return;}else{list_node *pre=NULL;list_node *current=head;list_node *next=head->next;while(n>0){pre=current;current=next;next=next->next;n--;}pre->next=next;free(current);} }1.7 刪除整個鏈表
? 刪除整個鏈表可不是直接free表頭就行了,要一個個遍歷整個鏈表,然后記錄前一個指針的位置進行一個一個free,原理和刪除一個類似,這里直接上代碼。
/*對整個鏈表進行刪除*/ void delete_list(list_node *head) {if(head!=NULL){list_node *pre=NULL;list_node *current=head;list_node *next=head->next;while(current!=NULL){pre=current;current=next;next=next->next;free(pre);}free(current);}else{printf("鏈表已經為空\n");} }1.8 鏈表的反轉
? 這個相對來說難一點,但是理解原理之后還是很容易的,有點類似于排序,但是有點區別。
反轉一步一步的過程應該是這樣,也有其他方法,自己查一下。
head->1->2->3->4->5 --------------------------------------原始鏈表
head->2->1->3->4->5 ---------------------------------------第一步
head->3->2->1->4->5 ---------------------------------------第二步
head->4->3->2->1->5 ---------------------------------------第三步
head->5->4->3->2->1 ---------------------------------------第四步
也就是相當于,每次把遍歷到的當前數據提到最前面。
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
/*鏈表的反轉*/ void reversal_list(list_node *head) {if(head!=NULL){list_node *current=head->next;list_node *next=current->next;while(next!=NULL){current->next=next->next;next->next=head->next;head->next=next;next=current->next;}}else{printf("鏈表為空\n");} }1.9 鏈表的排序
? 此次鏈表的排序使用的是選擇排序,相對簡單,使用冒泡等也能實現,簡單講一下冒泡的原理:
head->1->2->3->4 --------------------------------------原始鏈表
head->4->2->3->1 ---------------------------------------第一步
head->4->3->2->1 ---------------------------------------第二步
就是進行先讓第一個數和之后的每一個數比較,只要遇到比他大的就和第一個位置交換數據,然后第一個位置就是最大的數據,之后讓第二位與之后的每一個數據比較只要比他大的數就交換位置,…一直這么結束,排序完成。
/*使用選擇排序*/ void list_sort(list_node *head) {/*頭節點的data用來存儲總共有多少節點*/if(head==NULL)return;int i=0;int k=0;list_node *p=head->next;for(i=0;i<head->data-1;i++){list_node *s=p->next;for(k=i+1;k<head->data;k++){if((s->data)<(p->data)){int tem=p->data;p->data=s->data;s->data=tem;}s=s->next;}p=p->next;} }**持續更新鏈表的循環鏈表、雙向鏈表操作**總結
以上是生活随笔為你收集整理的单链表的创建、删除、反转、插入、排序操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【OJ每日一练】1039 - 阶乘数列和
- 下一篇: 启动docker时映射到宿主机时出现 /