關於鏈表_1

鏈表

動態地進行存儲的一種結構

其每一個元素節點分爲兩部分,數據域和指針域

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下運行通過】

(如有錯誤,敬請指正)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章