最近一直在忙着寫C語言的實驗實驗10。
一開始就是直接百度希望找到類似的例子進行學習和改進。當然也遇到了一些問題。
作爲數據結構的重要內容,先來看看鏈表的知識吧。以前沒接觸過鏈表,學到時,對鏈表的理解也是一團霧水。
最後自己理了一下。
這裏先說一下,鏈表有動態和靜態之分,靜態鏈表太簡單了,就不深入討論了,不過先來一個靜態鏈表的例子,我覺得有助於對動態鏈表的理解,同時,我也湊一下字數。
一個靜態鏈表的例子(實在看不懂,可以先看下面的鏈表的介紹)
/*
一個靜態鏈表的例子
*/
#include<stdio.h>
struct Student
{
long num;//學號
double score;//成績
struct Student *next;//指向下一個學生
};
int main()
{
struct Student a, b, c, *head;
//給結構體中的數據賦值
a.num = 10001;
a.score = 97;
b.num = 10002;
b.score = 85;
c.num = 10003;
c.score = 99;
/*這裏相當於把abcd連成一條鏈子,所以叫鏈表*/
head = &a;//頭指針指向a的地址
a.next = &b;//a的下一個空間指向b的地址
b.next = &c;//b的下一個空間指向c的地址
c.next = NULL;//最後附上空指針
//打印鏈表結構
do {
printf("%d %5.2f\n", head->num, head->score);
head = head->next;//打印完一個數據後使head指向下一個空間
} while (head!=NULL);
return 0;
}
運行結果:
1.1鏈表的組成
鏈表有兩個屬性,一個是數據屬性(域),另一個是指針屬性(域)
這個說法可能很拗口,下面我們看一個例子,通過例子來理解。
struct node
{
int date; //數據域,用於儲存數據
struct node *next; //指針域,存放地址,找到下一個數據所在的位置
};
圖解如下:(圖片來源於百度圖片)
1.2關於動態鏈表用到的幾個函數及其作用
先說一下什麼是動態鏈表吧
1.2.1什麼是動態鏈表
所謂建立動態鏈表是指在程序執行過程中從無到有的建立起一個鏈表,即一個一個的開闢節點和輸入各節點的數據,並建立起前後相連的關係。
使用動態鏈表存儲數據,不需要預先申請內存空間,而是在需要的時候才向內存申請。也就是說,動態鏈表存儲數據元素的個數是不限的,想存多少就存多少。
同時,使用動態鏈表的整個過程,只需操控一條存儲數據的鏈表。當表中添加或刪除數據元素時,需要通過 malloc 或 free 函數來申請或釋放空間。
1.2.2靜態鏈表和動態鏈表的區別
或許每個人最終都會有自己的理解,我也是看別人的理解的,這裏就不寫了,
去看看這篇文章https://blog.csdn.net/zhengqijun_/article/details/78192888
1.2.3使用動態鏈表過程中用到的兩個函數
1:動態申請內存 malloc 函數 (memory allocation)
其原型是:
extern void *malloc(unsigned int num_bytes);
說明:
1)void *
是未確定類型的指針,要用戶指定類型,如char *, int *,double *
若沒有指定則會報錯.
2)如果申請成功,則返回被指向的內存的指針,否則返回 NULL
2.動態內存釋放free()函數
其原型是:
void free(void *P)
說明:
與malloc 函數的功能相反,free()函數用來釋放由malloc給指針變量申請內存空間。
1.3動態鏈表的建立
個人覺得應該分成三個步驟
1)定義結構體類型-----構建鏈表
2)用malloc函數給節點開闢空間
3)給剛纔2)步驟開闢的節點傳入數據
4)繼續開闢空間
5)繼續給4)步驟開闢的節點傳入數據
6)之後就是開闢空間和傳入數據的重複操作
7)數據傳入完畢後,釋放空間,返回頭指針
說的在再清楚,不如看個例子吧。----建立一個動態鏈表的例子
#include<stdio.h>
#include<stdlib.h>
struct student{
long int num;//學號
float score;//成績
struct student*next;//指向下一個學生
};
int n=0;//有n個學生數據
/*創建鏈表函數*/
struct student* creat()
{
struct student *p1,*p2,*head;
p2=p1=(struct student*)malloc(sizeof(struct student));//創建一個動態存儲空間,p1,p2同時指向第一個結點
printf("please enter the first student:\n");
scanf("%ld,%f",&p1->num,&p1->score);
head=NULL;//頭指針置空
while(p1->num!=0)//以學生學號爲例,學號爲0時結束循環
{
n=n+1;
if(n==1)head=p1;//頭指針指向第一個數據
else p2->next=p1;//否則令表尾指針指向它,及鏈接到表尾
p2=p1;//p2指向新表尾
p1=(struct student*)malloc(sizeof(struct student));//繼續開闢動態存儲區
scanf("%ld,%f",&p1->num,&p1->score);//繼續輸入新結點數據
}
p2->next=NULL;//最終表尾結點的指針域置空
return head;//返回頭指針
}
/*輸出函數*/
void print(struct student *head)
{
struct student *p1;
p1=head;
while(p1->num!=0)
{
printf("\nnum:%ld,score:%f",p1->num,p1->score);
p1=p1->next;
}
}
void main()
{
struct student *head;
head=creat();//調用函數使得head指向空間首地址
printf("plese printf the num and score\n");
print(head);
}
做實驗10遇到的問題
1.1關於鏈表數據排序問題。
鏈表和數組有很大區別但是,排序算法都是一樣的。如果看懂了我之前寫的文章,淺談排序算法
就不難理解了。
參考鏈接https://blog.csdn.net/vectory0213/article/details/79168475?tdsourcetag=s_pcqq_aiomsg
個人體會: