雙向循環鏈表

雙向循環鏈表可理解爲一個閉環,通常爲了區別和操做方便,頭結點不存內容。如下是整個過程的代碼實現node

#include <stdio.h>
typedef int DATATYPE;//定義int的別名,以防止之後結點內容不是int了能夠方便替換
//定義鏈表結點結構體
struct node
{
	DATATYPE data;//數據域
	struct node *left;//指向前一個結點,用left其實更便於理解
	struct node *right;//指向後一個結點用right也是爲了便於理解,next也不錯
};
typedef struct node Node;//定義別名,方便書寫

Node * createDList();//建立雙向循環鏈表
int insertList1(Node *head, DATATYPE data);//頭插法插入
int insertList2(Node *head, DATATYPE data);//尾插法插入
void printDlist(Node * head);//打印鏈表內容
Node *searchNode(Node *head, DATATYPE find);//查找鏈表中的元素,雙向查找
void sortList1(Node *head, int len);//交換內容排序 基於冒泡
void sortList2(Node *head, int len);//交換指針排序 基於冒泡
void sortList3(Node *head, int len);//基於選擇排序的交換內容排序
int deleteNode(Node *head, DATATYPE data);//刪除指定節點
int lenList(Node *head);//求雙向循環鏈表的長度
void destroyList(Node *head);//求雙向循環鏈表的長度

int main(void)
{
	Node *head = createDList();//建立鏈表
	printf("head=%p\n", head);
	int i = 0;
	for (i = 7; i >= 0; i--)//爲鏈表賦初始測試值
//		insertList1(head, i);
		insertList2(head, i);
	printDlist(head);
	printf("——————\n");
	DATATYPE find = 3;//測試查找函數
	Node *search=searchNode(head, find);
	if (search != NULL)
		printf("search=%d\n", search->data);
	else
		printf("no such number\n");
	DATATYPE data = 0;
	deleteNode(head, data);//測試刪除函數
	int len = lenList(head);//測試求長度函數
	printf("len=%d\n",len);
//	sortList1(head, len);//測試排序函數
//	sortList2(head, len);
	sortList3(head, len);
	printDlist(head);
	destroyList(head);//銷燬全部結點
	printf("銷燬後的頭節點:=%p\n",head->right);
	printf("sizeof(head)=%d\n",sizeof(head));
	return 0;
}
//建立雙向循環鏈表,只須要返回一個頭結點就好
//雙向循環鏈表,就想一個閉環同樣的概念,通常頭結點中不存儲內容
Node * createDList()
{
	Node *head = (Node *)malloc(sizeof(Node));
	if (head)
	{
		head->left = head;
		head->right = head;
		return head;
	}
	else
		return NULL;
}
//頭插法插入,每次插入在頭結點後緊跟着
int insertList1(Node *head, DATATYPE data)
{
	Node *newNode = (Node *)malloc(sizeof(Node));
	if (newNode)
	{
		newNode->data = data;

		newNode->left = head;
		newNode->right = head->right;

		head->right = newNode;
		newNode->right->left = newNode;

		return 1;
	}
	else
		return -1;
}
//尾插法插入,每次插入在頭結點以前
int insertList2(Node *head, DATATYPE data)
{
	Node *newNode = (Node *)malloc(sizeof(Node));
	if (newNode)
	{
		newNode->data = data;
		head->left->right = newNode;
		newNode->left = head->left;
		newNode->right = head;
		head->left = newNode;
		return 1;
	}
	return -1;
}
//打印鏈表內容
void printDlist(Node * head)
{
	Node *p = head->right;
	while (p != head)
	{
		printf("%d\n", p->data);
		p = p->right;
	}
}
//查找鏈表中的元素,雙向查找
Node *searchNode(Node *head, DATATYPE find)
{
	Node *left = head;//left表示一個結點的前驅結點,初始值是頭結點
	Node *right = head;//right表示一個結點的後繼結點,初始值是頭結點
	do
	{
		left = left->left;//移動向前一個
		right = right->right;//移動向後一個
		if (left->data == find)//若是此時結點發現查找內容,就返回結點信息
			return left;
		if (right->data == find)//若是此時結點發現查找內容,就返回結點信息
			return right;	
	} while (left != right && left->left!=right);//當兩個結點相遇或者錯過期候終止循環
	//若是除了頭結點是偶數個,則相互錯過期候終止
	//若是除了頭結點是奇數個,則相遇時候終止查找
	return NULL;	
}
//交換內容排序 基於冒泡
void sortList1(Node *head, int len)
{
	int i = 0, j = 0;
	Node *p, *q;
	for (i = 0; i < len - 1; i++)
	{
		p = head->right;
		q = p->right;
		for (j = 0; j < len - 1 - i; j++)
		{
			if (p->data<q->data){
				p->data ^= q->data;
				q->data ^= p->data;
				p->data ^= q->data;
			}
			p = p->right;
			q = q->right;
		}
	}
	
}
//交換指針排序 基於冒泡
void sortList2(Node *head, int len)
{
	Node *p, *q;
	int i = 0, j = 0;
	for (i = 0; i < len - 1; i++)
	{
		p = head->right;
		q = p->right;
		for (j = 0; j < len - 1-i; j++)
		{
			if (p->data < q->data){
				q->left = p->left;
				p->left->right = q;
				p->right = q->right;
				q->right->left = p;
				q->right = p;
				p->left = q;

				q = p->right;
				
			}
			else{
				p = p->right;
				q = q->right;
			}
			
		}
	}
}
//基於選擇排序的交換內容排序
void sortList3(Node *head, int len)
{
	Node *p, *q, *max, *temp;
	DATATYPE t;
	p = head->right;
	q = p->right;
	int i = 0, j = 0;
	for (i = 0; i < len-1 ; i++)
	{
		if (p == head)
			break;
		max = p;
		q = p;
		for (j = i; j < len; j++)
		{
			if (q == head)
				break;
			if (max->data > q->data)
				max = q;
			q = q->right;
		}
		if (max != p)
		{
			t = max->data;
			max->data = p->data;
			p->data = t;		
		}
		p = p->right;
	}	
}
//基於選擇排序的交換指針排序,寫了可是一直出問題?
//刪除指定節點
int deleteNode(Node *head, DATATYPE data)
{
	Node *search = searchNode(head, data);
	if (search){
		search->left->right = search->right;
		search->right->left = search->left;
		free(search);
		return 1;
	}
	return 0;
}
//求雙向循環鏈表的長度
int lenList(Node *head)
{
	Node *p = head;
	int len = 0;
	while (p->right != head){
		len++;
		p = p->right;
	}
	return len;
}
//銷燬全部記錄
void destroyList(Node *head)
{
	Node *p = head->right;
	while (p != head)
	{
		p = p->right;
		free(p->left);
	}
	free(head);
	
}
相關文章
相關標籤/搜索