鏈表
動態地進行存儲的一種結構
其每一個元素(節點)分爲兩部分,數據域和指針域
n個節點離散分配,彼此通過指針相連
每個節點都只有一個前驅節點,都只有一個後繼結點
專業術語:
頭結點
頭結點的數據類型和首節點的類型一模一樣
頭結點是首節點前面的那個節點
頭結點並不存放有效數據
設置頭結點的目的是爲了方便對鏈表的操作
頭指針
存放頭結點地址的指針變量(即指向頭結點的指針變量,下同)
首節點
存放第一個有效數據的結點
尾節點
存放最後一個有效數據的結點
下面舉一個例子
例1:
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
//定義可一個鏈表節點的數據類型
struct Node
{
int data; //8行 數據域
struct Node * pNext; //9行 指針域
};
//函數聲明
struct Node * create_list(void);
void traverse_list(struct Node *);
int main(void)
{
struct Node * pHead = NULL; //18行
pHead = create_list(); //20行
traverse_list(pHead); //21行
return 0;
}
struct Node * create_list(void)
{
int len; //28行
int i;
int val; //30行
struct Node * pHead = (struct Node *)malloc(sizeof(struct Node))//32行
if (NULL == pHead)
{
printf("分配失敗, 程序終止!\n");
exit(-1);
}
struct Node * pTail = pHead;
pTail->pNext = NULL;
printf("請輸入您需要生成的鏈表節點的個數: len = ");
scanf("%d", &len);
for (i=0; i<len; ++i)
{
printf("請輸入第%d個節點的值: ", i+1);
scanf("%d", &val);
struct Node * pNew = (struct Node *)malloc(sizeof(struct Node));
if (NULL == pNew)
{
printf("分配失敗, 程序終止!\n");
exit(-1); //終止程序
}
pNew->data = val;
pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
}
return pHead;
}
void traverse_list(struct Node * pHead)
{
struct Node * p = pHead->pNext;
while (NULL != p)
{
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
return;
}
輸出結果爲:
當輸入一個整數數字時(假設爲3),則會提示輸入要存儲的整數,請輸入第1個節點的值:,然後輸入一個整數數字,接着就是輸入第二個、第三個,最終是將輸入的數字保存在鏈表中並輸出
對於鏈表,一個元素(節點)分爲數據域和指針域,數據域存儲數據,指針域存儲下一個元素的地址,
本程序中,第8行和第9行表示的就是一個元素的數據域和指針域,而它們所在的結構體表示鏈表中的一個元素;而第18行的pHead則是用來存放鏈表頭結點的地址;第20行 create_list() 的功能是:創建一個非循環單鏈表,並將該鏈表的頭結點的地址付給pHead,第21行是將鏈表輸出,traverse的意思就是遍歷,而遍歷的意思是依次訪問每個節點,這裏可以理解爲輸出
接下來,28行和30行分別表示“存放有效節點的個數”和“臨時存放用戶輸入的結點的值”;32行是分配了一個不存放有效數據的頭結點
對了,還要說的是一個關鍵字typedef,這是個類型別名,具體用法見下例
例2:
# include <stdio.h>
int main(void)
{
typedef int LISI;
LISI i= 0; //等價於int i = 0;
printf("%d\n", i);
return 0;
}
輸出結果爲:
由上可知typedef是爲int再多取一個名字字(這裏是LISI),在以下的代碼裏而LISI和int,用哪個都行,這麼做爲的是簡單,當然,上面那個程序看不到什麼簡單,下面再舉一個例子
例3:
# include <stdio.h>
typedef struct student
{
int sid;
char name[100];
char sex;
}ST;
int main(void)
{
struct student a;
ST s;
a.sid = 333;
s.sid = 100;
printf("%d %d\n",a.sid, s.sid);
return 0;
}
輸出結果爲:
由上可知,ST等價於struct student
如果將ST變爲* PST,則* PST等價於struct student *
另外,這樣寫也可以
typedef struct student
{
int sid;
char name[100];
char sex;
}ST, *PST;
這時同時聲明瞭ST和* PST兩個類型
需要說明的是,ST和PST這樣的名字可以隨便取(只要不是關鍵字),但一般都大寫
【所有代碼均在windows系統下C-Free5.0下運行通過】
(如有錯誤,敬請指正)