【C++基礎複習01】結構體和連結串列
結構體
結構體是一個可以包含不同資料型別的一個結構,使用修飾符struct
進行定義。結構體可以在一個結構中宣告不同的資料型別,並且只有結構相同的結構體變數可以相互賦值。
先來看例子,如下構造一個結構體:
struct student
{
int id;
char name[9];
int Chinese,math,English;
double average;
};
以上就是由個人定義的一個結構體student,其中的屬性(id,Chinese,average)等被稱之為結構體成員,並且有自己的資料型別。需要注意的是,在{}結尾處,要加上一個分號 ; 否則會導致語法錯誤。另外,描述的結構體並不佔用記憶體空間,只有當用這種新的資料型別定義變數,陣列,申請變數或申請堆陣列時候才要分配空間。
接下來我們利用這個結構體來建立一些變數並來訪問,程式碼片段如下:
student s; //建立一個student物件
student *ps=&s; //定義一個指標變數指向s
student &rs=s; //定義一個引用(不佔用空間)
s.id=1;
strcpy(s.name,"李詩珺"); //利用字串複製對s.name賦值,不能用s.name="XX"
ps->Chinese=95; //用指標變數訪問目標物件成員
(*ps).math=90; //等價於 ps->math=90
s.English=92;
rs.average=(s.Chinese+rs.English+ps->math)/3.0;
//引用訪問“繫結”的目標物件成員
cout<<s.name<<"的平均成績為"<<s.average<<endl;
需要注意的是,優先順序為2的圓點運算子“.”用於結構體物件訪問其成員;箭頭運算子“->”用於結構體指標訪問目標物件成員。這樣一來,基本就掌握了結構體的基本用法了。
單向連結串列
在理解了結構體的基礎上,再來認識連結串列就比較容易了。能夠單方向聯絡的連線方式被稱為單向連結串列,構成單向連結串列的元素被稱為結點。結點應該具有承載資料及指向下一個結點的能力。在鏈式連線結構中,刪除某個結點只需要將該節點儲存的下一個結點地址“交給”上一個結點即可。由於結點個數以及各個結點在記憶體中的地址都很容易得到,所以將單向連結串列傳遞給函式時,只需要傳遞鏈首地址。
先來試著定義一個結點:
struct memory //定義記憶體空間結點
{
int address; //分割槽首地址
int space; //空間大小
bool status; //狀態位
memory *next; //同類指標,指向下一個記憶體空間的地址
};
以上便定義了一種型的資料型別,先來建立一條空連結串列:
memory *head=NULL;
建立完畢之後,就要對這條單向連結串列進行操作了。首先得加入元素,也就是在首節點處再插入結點,插入函式如下:
void InsertBeforeHead(memory *&head,int space,bool status,int address)
{
memory *p=new memory ; //建立一個新結點
p->address=address;
p->space=space; //賦值操作
p->status=status;
p->next=head; //新結點將原鏈首結點當成下一個結點
head=p; //head記錄新結點的地址,成為新的鏈首地址
//最先定義的head到最後會成為鏈尾
}
在連結串列建立完成之後(一般建立空連結串列),然後利用上述函式新增一個新結點到鏈首前成為新的鏈首。當插入完成之後,就完成了一條單連結串列的建立。接下來附上一些常用的連結串列操作函式。
刪除鏈首結點的函式:
void DeleteHead(memory *&head)
//這裡需要使用引用,因為要直接修改head的指向
{
memory *p=head; //記錄當前鏈首結點地址
if(head!=NULL) //判斷是否為空連結串列
{
head=head->next; //下一個結點成為新的鏈首結點,相當於刪除了當前結點
delete p; //釋放原鏈首結點
}
}
遍歷函式的運用:
memory *p;
int n; //統計結點個數
for(p=head;p!=NULL;p=p->next)
{ n++; //統計計算
cout<<p->space<<endl; //遍歷輸出資料
}
釋放所有結點:
while(head!=NULL)
{
p=head;
head=head->next; //使head指向的下一個結點成為頭結點
delete p; //釋放空間
}
插入一個結點:
void Insert(int i,int e,int n,memory *&head)
//i表示插入位置,e表示插入的資料,n表示結點個數
{
memory *q=new memory ; //建立一個新結點,即為要插入的結點
memory *p; //用於遍歷結點
q->space=e; //賦值
q->status=0;
q->address=0;
if(i>n||i<0) //判斷是否越界
return ;
if(i==1) //即插入位置為頭結點
{
q->next=head; //成為鏈首
head=q;
}
for(p=head;i!=0,p!=NULL;p=p->next,i--); //找到插入的位置
if(i==n) //即插入位置為鏈尾
{
p->next=q; //直接在鏈尾插入
}
else
{
q->next=p->next; //q代替本來p的位置,指向p的下一個元素
p->next=q; //p的下一個結點指向q
}
}
刪除一個結點:
void DeleteHead2(int e,memory *&head) //e用來確定刪除哪個結點
{
memory *p,*q;
p=head; //前哨結點
q=head->next; //用於定位需要刪除的結點
while(q!=NULL)
{
if(q->space==e) //找到該結點
{
p->next=q->next; //使待刪結點脫鏈
delete q;
break;
}
p=p->next; //若未找到,則往前推進一個結點
q=q->next;
}
}
以上是單向連結串列的一些基礎操作函式,掌握了這些就基本能夠對單向連結串列進行增刪查改的操作了。
雙向連結串列
從上文的單向連結串列中可以看出,單向連結串列只有指向下一個結點的指標,並不能訪問其前驅元素,所以在訪問單連結串列的時候,只能順序訪問,但在實際操作中,可能是一件比較麻煩的事情,所以接下來要來學習一下雙向連結串列。
說來雙向連結串列其實很簡單,無非是在之前的單向連結串列之前加入一個前驅指標pre,後繼指標next不變。這樣,無論是順序遍歷還是逆序遍歷都很方便,可以快速找到上一個結點的位置。
首先來看一下如何定義雙向連結串列的結點:
struct node
{
int data;
node* prev; //前驅指標
node* next; //後繼指標
};
那這樣看來,雙向連結串列的頭結點前驅指標為空,尾結點的後繼指標為空,也非常好判斷。
結合單向連結串列實現的程式碼,雙向連結串列也非常容易實現,而比較容易犯錯的地方就是新增和刪除結點,其他程式碼省略了,接下來附上幾段虛擬碼,實現新增和刪除結點。
新增元素:
我們假設要插入的結點為node,插入位置的結點為current,插入位置的下一個結點為next。
current->next=node;
node->prev=current;
node->next=next;
next->prev=node;
程式碼並不難,但要理解。要求是將node插入current和next結點之間,那麼要修改的指標就是:current的後繼,next的前驅,以及node的前驅和後繼。我們要讓current的後繼指向node,讓next的前驅指向node,這樣就能找到node的位置了。接下來修改node的前驅後繼指標,分別指向current和next,就完整了。
刪除結點:
我們假設要刪除的結點為node,前驅結點為current,後繼結點為next.
current->next=next;
next->prev=current;
delete node;
刪除結點相對於插入結點更簡單,只需要修改要刪除結點的前驅結點和後繼結點的指標即可。將前驅結點的後繼指向後繼結點,然後將後繼結點的前驅指向前驅結點,最後別忘記釋放node的空間。這樣就完成了刪除結點的操作。
其他的查詢修改操作也比較容易實現,這裡筆者就不再贅述了。能夠了解上述的函式操作,那在單連結串列以及雙向連結串列的操作方面,應該都不會有問題了。
相關文章
- 資料結構基礎 連結串列資料結構
- Redis基礎資料結構之連結串列Redis資料結構
- 連結串列基礎總結
- 資料結構練習題(順序表和單連結串列)C++資料結構C++
- 連結串列基礎2(超簡單)--單連結串列的插入和刪除
- 實戰PHP資料結構基礎之雙連結串列PHP資料結構
- 實戰PHP資料結構基礎之單連結串列PHP資料結構
- 資料結構學習--連結串列資料結構
- 【C++ 資料結構:連結串列】二刷LeetCode707設計連結串列C++資料結構LeetCode
- Go 語言 結構體連結串列Go結構體
- 連結串列part01
- C++資料結構連結串列的基本操作C++資料結構
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 演算法與資料結構基礎 - 連結串列(Linked List)演算法資料結構
- 資料結構-單連結串列、雙連結串列資料結構
- 資料結構——單連結串列的C++實現資料結構C++
- Redis 的基礎資料結構(一) 可變字串、連結串列、字典Redis資料結構字串
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- 學習 JavaScript 資料結構(二)——連結串列JavaScript資料結構
- 重溫四大基礎資料結構:陣列、連結串列、佇列和棧資料結構陣列佇列
- 資料結構實驗之連結串列七:單連結串列中重複元素的刪除資料結構
- 複雜連結串列的複製
- 資料結構 - 連結串列資料結構
- 連結串列-資料結構資料結構
- 資料結構—連結串列資料結構
- 資料結構--連結串列資料結構
- 資料結構-連結串列資料結構
- 構建連結串列
- C++ STL list連結串列C++
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 反轉連結串列、合併連結串列、樹的子結構
- C\C++之用結構體實現連結串列的建立、遍歷、結點插入、結點刪除C++結構體
- 01.結構體和方法結構體
- c++基礎十(流程結構)C++
- L2-002 連結串列去重(複習)
- 資料結構之連結串列資料結構
- 資料結構之「連結串列」資料結構
- JavaScript資料結構--連結串列JavaScript資料結構