數據結構:循環雙向鏈表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ElemType int

typedef struct LNode{
	ElemType data;
	struct LNode *prior;
	struct LNode *next;
}LNode, *LinkList;

// 帶頭節點的初始化
bool InitList(LinkList &headList)
{
	headList = (LNode*) malloc(sizeof(LNode));
	if(headList == NULL){
		return false;
	}
	// 初始化時循環雙鏈表的頭結點的前後結點都指向自己 
	headList->next = headList; 
	headList->prior = headList;	 
	return true;
}
// 按位查找 
LNode* GetElem(LinkList headList, int i)
{
	if(i < 0){
		return NULL;
	}
	LNode *p = headList;
	int j = 0;
	while(j < i){
		p = p->next;
		j++;
		if(p == headList){ // p再次等於headList表示循環一週了 
			return NULL;
		}
	}
	return p;
}
// 按值查找
LNode* LocateElem(LinkList headList, ElemType e)
{
	LNode *p = headList->next;
	while(p != headList && p->data != e){
		p = p->next;
	}
	return p;
}
// 在指定結點p後插入元素e
bool InsertNextNode(LNode *p, ElemType e)
{
	if(p == NULL){
		return false;
	}
	LNode *node = (LNode *)malloc(sizeof(LNode));
	if(node == NULL){ // 內存分配失敗 
		return false;
	}
	node->data = e;
	node->next = p->next; // 連接node的後繼結點 
	p->next->prior = node; // 讓node成爲其後繼結點的前驅 
	node->prior = p; // node前向指針指向它的前驅 
	p->next = node; // node成爲p的後繼結點 
//	printf("%d\n", p->next->data);
	return true;
}
// 在第idx的位置上插入e 
bool ListInsert(LinkList &headList, int idx, ElemType e)
{
	if(idx < 1){
		return false;
	} 
	LNode *p = GetElem(headList, idx-1); 
	return InsertNextNode(p, e); // 調用在指定結點後插入元素的函數 
}
// 在指定結點p之前插入元素e
bool InsertPriorNode(LinkList &headList, LNode *p, ElemType e)
{
	LNode *tmp = headList;
	tmp = p->prior;	// 得到p結點的前一個結點 
	LNode *node = (LNode *)malloc(sizeof(LNode));
	if(node == NULL){
		return false;
	}
	
	node->data = e;
	node->prior = p->prior;
	p->prior->next = node;
	node->next = p;
	p->prior = node;
	return true;
}

// 刪除操作 刪除第idx個位置的元素
bool ListDelete(LinkList &headList, int idx)
{
	if(idx < 0){
		return false;
	}
	LNode *p = GetElem(headList, idx-1); // 找到第idx-1個結點 
	if(p == NULL || p->next == NULL){ // 如果idx無效 
		return false;
	}
	LNode *tmp = p->next; // tmp爲當前要刪除的結點 
	p->next = tmp->next;
	tmp->next->prior = p;
	free(tmp); 
	return true; 
}
// 刪除指定結點 O(1)方法
bool DeleteNode(LinkList &headList, LNode *p)
{
	if(p == NULL){
		return false;
	}
	LNode *priorNode = p->prior; // 被刪除結點的前驅結點 
	LNode *nextNode  = p->next; // 被刪除結點的後繼結點 
	priorNode->next = nextNode;
	nextNode->prior = priorNode;
	free(p);
	return true;
}


// 帶頭節點的判空方法
bool IsEmpty(LinkList &headList)
{
	return (headList->next == headList);
}
// 求表長 
int Length(LinkList headList)
{
	LNode *p = headList;
	int len = 0;
	while(p->next != headList){
		p = p->next;
		len++;
	}
	return len;
}
// 尾插法建立雙鏈表
LinkList ListTailInsert(LinkList &headList)
{
	headList = (LinkList)malloc(sizeof(LNode)); // 建立頭結點
	headList->next = headList;
	headList->prior = headList; 
	LNode *tail = headList;
	ElemType e;
	while(scanf("%d", &e) != EOF){
		LNode *newnode = (LNode *)malloc(sizeof(LNode));
		newnode->data = e;
		newnode->next = headList;
		headList->prior = newnode;
		tail->next = newnode;
		newnode->prior = tail;
		tail = newnode;
	}
	tail->next = headList;
	headList->prior = tail;
	return headList;
}
// 頭插法建立單鏈表
LinkList ListHeadInsert(LinkList &headList) 
{
	headList = (LinkList)malloc(sizeof(LNode));	// 建立頭結點 
	headList->next = headList;
	headList->prior = headList; 
	LNode *head = headList;
	ElemType e;
	while(scanf("%d", &e) != EOF){
		LNode *newnode = (LNode *)malloc(sizeof(LNode));
		newnode->data = e;
		newnode->next = head->next;
		head->next->prior = newnode;
		newnode->prior = head;
		head->next = newnode; 
	}
	headList = head;
	return headList;
}
// 銷燬單鏈表
bool ListDestroy(LinkList headList)
{
	if(headList == NULL){
		return false;
	}
	LNode *p = headList->next;
	if(p != headList){
		headList->next = p->next;	// 刪除p結點 
		free(p);	// 釋放p結點空間 
		p = headList->next; // p指向新的結點 
	}
	free(headList);	// 釋放頭結點 
	return true;
}

int main()
{
	LinkList headList;
	bool flag = false;
	flag = InitList(headList);
	printf("%d\n", flag);
//	ListTailInsert(headList);
	ListHeadInsert(headList); 
	for(int i = 0; i < 10; i++){
		ListInsert(headList, i+1, i+1);
	}
	
	// 調用鏈表操作函數 
	ListInsert(headList, 6, 5);
	InsertPriorNode(headList, headList->next->next, 10); 

	ListDelete(headList, 8);
	DeleteNode(headList, headList->next->next);
	DeleteNode(headList, headList->next->next);
	
	printf("Here\n");
	int i = 1;
	for(LNode *p = headList->next; p != headList; p = p->next){
		printf("第%d個結點的值是:%d\n", i++, p->data);
	}
	printf("表長是%d\n", Length(headList)); 
	return 0;
}

 

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