Linux C 單向連結串列2
#include <stdlib.h>
/*節點型別結構體*/
typedef struct node_t {
void* data; //節點的資料域
struct node_t *next; //節點的後繼指標域
}linknode_t, *linklist_t;
linklist_t CreateEmptyLinklist(); //利用頭結點來建立一個空連結串列(頭結點)
void DestroyLinklist(linklist_t list); //刪除連結串列函式
void ClearLinklist(linklist_t list); //刪除連結串列裡面節點函式
int EmptyLinklist(linklist_t list);//判斷連結串列是否為空連結串列函式
int LengthLinklist(linklist_t list);//獲取連結串列長度函式
int GetLinklist(linklist_t list, int at, void **data);//連結串列的某個節點獲取函式
int SetLinklist(linklist_t list, int at, void *data);//連結串列的某個節點設定函式
int InsertLinklist(linklist_t list, int at,void *data); //連結串列的某個節點插入函式
int DeleteLinklist(linklist_t list, int at);//刪除連結串列某個節點函式
linklist_t ReverseLinklist(linklist_t list); //連結串列反轉函式
*
* 入口引數:
* 無
* 返回值:
* linknode_t結構體;
* 函式描述:
* 利用頭結點來建立一個空連結串列(頭結點);
* 注意事項:
* 無;
*/
linklist_t CreateEmptyLinklist()
{
linklist_t list;
list = (linklist_t)malloc(sizeof(linknode_t)); //結構指標分配空間;
if (NULL != list) {
list->next = NULL; //下一個Node節點為空;
}
return list;
}
/*
* 入口引數:
* linklist_t結構指標;
* 返回值:
* 無;
* 函式描述:
* 刪除連結串列函式;
* 注意事項:
* 無;
*/
void DestroyLinklist(linklist_t list)
{
if (NULL != list) {
ClearLinklist(list);
free(list);
}
}
/*
* 入口引數:
* linklist_t結構指標;
* 返回值:
* 無;
* 函式描述:
* 刪除連結串列裡面節點函式;
* 注意事項:
* 無;
*/
void ClearLinklist(linklist_t list)
{
linknode_t *node; //指向Node節點的時候被移除
if (NULL == list) return;
while (NULL != list->next) {
node = list->next;
list->next = node->next;
free(node);
}
return;
}
/*
* 入口引數:
* linklist_t結構指標;
* 返回值:
* 無;
* 函式描述:
* 獲取連結串列長度函式;
* 注意事項:
* 無;
*/
int LengthLinklist(linklist_t list)
{
int len = 0;
linknode_t *node; //迭代節點
if (NULL == list) return -1;
node = list->next; // 迭代節點指第一個資料節點
while (NULL != node) {
len++;
node = node->next;
}
return len;
}
/*
* 入口引數:
* linklist_t結構指標;
* 返回值:
* 無;
* 函式描述:
* 判斷連結串列是否為空連結串列函式;
* 注意事項:
* 無;
*/
int EmptyLinklist(linklist_t list)
{
if (NULL != list) {
if (NULL == list->next) { //判斷連結串列是否為空,為空返回1
return 1;
} else { //判斷連結串列是否為空,不為空返回1
return 0;
}
} else {
return -1;
}
}
/*
* 入口引數:
* list 結構指標;
* at 節點位置;
* data 獲取資料;
* 返回值:
* 無;
* 函式描述:
* 連結串列的某個節點獲取函式;
* 注意事項:
* 無;
*/
int GetLinklist(linklist_t list, int at, void **data)
{
linknode_t *node; //迭代節點
int pos;
if (NULL == list) return -1;
if (at < 0) return -1;
node = list->next; //第一個節點賦值迭代節點
pos = 0;
while (NULL != node) {
if (at == pos) {
if (NULL != data) {
*data = node->data;
}
return 0;
}
node = node->next; //指向下一個節點
pos++;
}
return -1;
}
/*
* 入口引數:
* list 結構指標;
* at 節點位置
* data 設定資料
* 返回值:
* 無;
* 函式描述:
* 連結串列的某個節點設定函式;
* 注意事項:
* 無;
*/
int SetLinklist(linklist_t list, int at, void *data)
{
linknode_t *node; //迭代節點
int pos;
int found = 0;
if (!list) return -1;
if (at < 0) return -1;
node = list->next; //初始化迭代節點
pos = 0;
while (NULL != node) {
if (at == pos) {
found = 1; //插入節點的標誌
node->data = data; //把資料賦值給節點資料域
break;
}
node = node->next; //指向下一個節點
pos++;
}
if (1 == found) { //如果設定資料成功返回為0;
return 0;
} else { //如果設定資料失敗返回為-1;
return -1;
}
}
/*
* 入口引數:
* list 結構指標;
* at 節點位置
* data 設定資料
* 返回值:
* 無;
* 函式描述:
* 連結串列的某個節點插入函式;
* 注意事項:
* 無;
*/
int InsertLinklist(linklist_t list, int at, void *data)
{
linknode_t *node_prev, *node_at, *node_new; //初始化迭代節點
int pos_at;
int found = 0;
if (NULL == list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
node_new = malloc(sizeof(linknode_t)); //分配空間
if (NULL == node_new) {
return -1;
}
node_new->data = data; /* assigned value */
node_new->next = NULL; //節點如果插入超過連結串列長度的位置,會接到尾節點後面,這樣,node_new成了尾節點,node_new->next = NULL
node_prev = list; //跟隨指標,幫助我們更好的定位
node_at = list->next; //遍歷指標
pos_at = 0;
while (NULL != node_at) {
if (pos_at == at) {
found = 1; //找到正確的位置,跳出迴圈
break;
}
node_prev = node_at; //跟隨指標先跳到遍歷指標的位置
node_at = node_at->next; //遍歷指標跳到下一個節點的位置
pos_at++;
}
if (found) {
node_new->next = node_at; //插入的節點next指向node_at
node_prev->next = node_new; //插入節點的前一個節點
} else {
/*若是沒找到正確的位置,即所插入位置超越了連結串列的長度,則接到尾節點的後面,
同樣,這樣適用於空連結串列,這樣我們可以建立一個空連結串列,利用這個函式,實現連結串列的初始化*/
node_prev->next = node_new;
}
return 0;
}
/*
* 入口引數:
* list 結構指標;
* at 節點位置
* 返回值:
* 無;
* 函式描述:
* 刪除連結串列某個節點函式;
* 注意事項:
* 無;
*/
int DeleteLinklist(linklist_t list, int at)
{
linknode_t *node_prev, *node_at;
int pos_at;
int found = 0;
if (!list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
node_prev = list;
node_at = list->next;
pos_at = 0;
while (NULL != node_at) {
if (pos_at == at) {
found = 1; //找到對應的位置,跳出迴圈
break;
}
node_prev = node_at; //跟隨指標,幫助我們更好的定位
node_at = node_at->next; //遍歷指標跳到下一個節點的位置
pos_at++;
}
if (found) {
node_prev->next = node_at->next; //移除對應的節點
free(node_at);
return 0;
} else {
return -1;
}
}
/*
* 入口引數:
* list 結構指標;
* 返回值:
* 無;
* 函式描述:
* 連結串列反轉函式;
* 注意事項:
* 無;
*/
linklist_t ReverseLinklist(linklist_t list)
{
linknode_t *node; //迭代節點
linknode_t *node_prev; //迭代之前節點
linknode_t *node_next; //迭代之後節點
if (NULL == list) return NULL;
node_prev = NULL;
node = list->next;
while (NULL != node) {
node_next = node->next; //迭代節點指向下一個節點
/*當迭代節點指向最後一個節點,連結串列頭節點指向最後一個節點,
連結串列最後一個節點成為頭節點*/
if (NULL == node_next) {
list->next = node;
}
/*反轉連結串列直接的節點,確保當前節點指向先前的節點不是下一個節點*/
node->next = node_prev;
/*反轉連結串列位置*/
node_prev = node;
node = node_next;
}
return list;
}
/**********************************測試程式******************************************/
typedef struct{
char a[10];
char b;
}data_t;
int main()
{
int i;
data_t *data;
linklist_t p;
data_t *c;
p = CreateEmptyLinklist();
for(i = 0;i < 5;i++)
{
c =(data_t *)malloc(sizeof(data_t));
sprintf(c->a,"a%d",i);
c->b=i;
InsertLinklist(p,i,(void*)c);
}
//ReverseLinklist(p);
printf("The length of the list is:%d\n",LengthLinklist(p));
for(i = 0;i < 5;i++)
{
GetLinklist(p,i,&data);
printf("The NO of this list is:%s\n",data->a);
printf("The NO of this list is:%d\n",data->b);
}
return 0;
}