1. 程式人生 > >C語言雙向連結串列的實現(簡單實現)

C語言雙向連結串列的實現(簡單實現)

最近有時間看了資料結構的雙向連結串列,其實和單向連結串列的規則是一樣的,只不過在定義節點的時候比單向連結串列多定義i一個指向前一個節點的指標就可以了,在插入節點和刪除節點的時候要注意,畫圖是最好的方法。

雙向使用的時候重要的是獲得連結串列頭和連結串列尾,下面有獲取的相關函式。

// copyright reserved by GongXu
// doubly linked list for simple using
#include<stdio.h>
#include<stdlib.h>
/*雙向連結串列的關鍵是在節點上定義兩個指標,一個指向前一個節點,另一個指向後一個節點*/
typedef int Data_type;
struct Node_doubly {
	Data_type data;
	struct Node_doubly* prev;
	struct Node_doubly* next;
};
typedef struct Node_doubly* Node_p;
/*創造一個連結串列返回頭結點*/
Node_p create_list(){
	Node_p list_head = (Node_p)malloc(sizeof(struct Node_doubly));
	list_head->prev = NULL;
	list_head->next = NULL;
	return list_head;
}

/*建立一個連結串列的節點,也就是開闢一個記憶體空間儲存節點的資料*/
Node_p create_list_node(Data_type  data){
	Node_p new_node = malloc(sizeof(struct Node_doubly));
	new_node->data = data;
	return new_node;
};
/*在連結串列的頭部位置新增資料*/
void insert_node_by_head (Node_p list,Data_type data){
	Node_p new_node = create_list_node(data);
	//插入時已經有節點
	if (list->next){
		list->next->prev = new_node;
		new_node->next = list->next;
		new_node->prev = list;
		list->next = new_node;
	}
	// 插入的時候沒有節點,只有首節點
	else{
		list->next = new_node;
		new_node->prev = list;
		new_node->next = NULL;

	}
	
	
}
/*在連結串列的頭部位置刪除節點*/
void delete_node_by_head(Node_p list){
	Node_p ptr = list->next;
	list->next = ptr->next;
	free(ptr);
}
/*在特定的資料點刪除連結串列節點*/
void delete_node_by_pos(Node_p list, Data_type pos){
	Node_p p_for = list;
	Node_p p_aft = list->next;
	while (p_aft->data != pos){
		p_for = p_aft;
		p_aft = p_aft->next;
		if (p_aft == NULL){
			printf("Not  finding Positon to delete\n ");
			return;
		}
	}
	Node_p ptr = p_aft->next;
	p_for->next = ptr;
	ptr->prev = p_for;
	free(p_aft);

}
/*返回雙向連結串列的尾節點*/
Node_p get_lastNode(Node_p list){
	Node_p ptr = list->next;
	Node_p ptr_after = ptr;
	if (ptr){
		while (ptr != NULL){
			ptr_after = ptr;
			ptr = ptr->next;
		}
		return ptr_after;
	}
	else
		return list;
}

/*列印連結串列的全部資料,使用首節點開始列印*/
void print_list(Node_p list){
	Node_p ptr = list->next;
	while (ptr != NULL){
		printf("%d\t", ptr->data);
		ptr=ptr->next;
	}
	printf("\n");
}
/*列印連結串列的全部資料,使用尾節點開始列印*/
void print_list_with_last(Node_p last_list){
	Node_p ptr = last_list;
	while (ptr->prev != NULL){
		printf("%d\t", ptr->data);
		ptr = ptr->prev;
	}
	printf("\n");
}
/*銷燬連結串列,主要是把申請的記憶體還給記憶體管理器*/
void destroy_list(Node_p list){
	Node_p ptr = list;
	
	Node_p ptr_q ;
	while (ptr != NULL){

		ptr_q=ptr->next;
		ptr->next=ptr_q->next;
		free(ptr_q);
		ptr = ptr->next;
	}
	list = NULL;
}

/*程式的主函式*/
int main(void){
	// 建立一個連結串列返回頭結點
	Node_p List_head=create_list();
	// 插入資料
	insert_node_by_head(List_head, 10);
	insert_node_by_head(List_head, 11);
	insert_node_by_head(List_head, 12);
	insert_node_by_head(List_head, 13);
	//顯示資料頭結點開始
	print_list(List_head);
	//使用尾節點顯示資料
	Node_p last_list = get_lastNode(List_head);
	print_list_with_last(last_list);
	print_list(List_head);
	delete_node_by_head(List_head);
	delete_node_by_head(List_head);
	print_list(List_head);
	delete_node_by_pos(List_head,11);
	print_list(List_head);
	//銷燬連結串列
	destroy_list(List_head);
	print_list(List_head);
	while (1);

}