數據結構第五天

一、雙向鏈表

1、單鏈表構成的循環鏈表
最後一個結點本來指向NULL,改爲指向頭結點或者第一個結點。
實現方法,將原來指向NULL的地方改成指向ls->head,或者ls->head->next。
While()循環的條件改爲!= ls->head或者ls->head->next。
在這裏插入圖片描述

#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>

List *Creat()
{	
	List *ls = (List *)malloc(sizeof(List)/sizeof(char));
	if(NULL == ls)
		return NULL;
	
	ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = NULL;
	ls->head->pre  = NULL;
	return ls;
}

//頭插
BOOL inster_head(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = ls->head->next;
	pa->pre  = ls->head;
	ls->head->next = pa;
	if(pa->next != NULL)
		pa->next->pre  = pa; 

	return TRUE;
}

//尾插
BOOL inster_last(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = NULL;
	
	Node *tmp = ls->head;
	while(tmp->next)
	{
		tmp = tmp->next;
	}
	tmp->next = pa;
	pa->pre   = tmp;
	
	return TRUE;
}

//鏈表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
	if(NULL == ls || index < 1)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == pa)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(tmp == NULL)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	pa->data = data;		//要插入的數據
	pa->next = tmp->next;	
	pa->pre  = tmp;
	tmp->next = pa;	
	if(pa->next != NULL)	
	pa->next->pre = pa;
	
	return TRUE;
}

//刪除數據(按位置)
BOOL delete_index(List *ls,int index)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(NULL == tmp || NULL == tmp->next)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;
	if(p->next != NULL)
		p->next->pre = tmp;
	free(p);
	
	return TRUE;
}

//刪除數據(按數據)
BOOL delete_pos(List *ls,Data data)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next)
	{
		if(tmp->next->data == data)
		{	
			Node *p = tmp->next;
			tmp->next = p->next;
			if(p->next != NULL)
				p->next->pre = tmp;
			free(p);
			return TRUE;
		}
		tmp = tmp->next;
	}
	return FALSE;
}

//逆序
BOOL Reverse(List *ls)
{
	if(NULL == ls || NULL == ls->head)
		return ERROR;
	
	if(NULL == ls->head->next)
	{
		printf("鏈表爲空\n");
		return FALSE;
	}
	if(NULL == ls->head->next->next)
	{
		printf("鏈表只有1個無需逆序\n");
		return FALSE;
	}
		
	Node *cur = ls->head->next;			//第一個結點
	
	while(cur->next)
	{
		Node *tmp = cur->next;			//保存指向下一個地址
		cur->next = cur->pre;
		cur->pre  = tmp;
		
		cur = tmp;
	}
	
	ls->head->next->next = NULL;
	cur->next = cur->pre;
	ls->head->next = cur;
	
	return TRUE;
}

//打印
void Display(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head->next;
	while(tmp)
	{
		printf("%-4d",tmp->data);
		tmp = tmp->next;
	}
	printf("\n");
}

//刪除鏈表
void Destroy(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next)
	{	
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

二、循環鏈表

1、逆序
在這裏插入圖片描述在這裏插入圖片描述

//循環鏈表
#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>

//創建
List *Creat()
{	
	List *ls = (List *)malloc(sizeof(List)/sizeof(char));
	if(NULL == ls)
		return NULL;
	
	ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = ls->head;
	
	return ls;
}

//頭插
BOOL inster_head(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = ls->head->next;
	ls->head->next = pa;

	return TRUE;
}

//尾插
BOOL inster_last(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = ls->head;
	
	Node *tmp = ls->head;
	while(tmp->next != ls->head)
	{
		tmp = tmp->next;
	}
	tmp->next = pa;
	
	return TRUE;
}

//鏈表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
	if(NULL == ls || index < 1)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == pa)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(tmp == ls->head)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	pa->data = data;		//要插入的數據
	pa->next= tmp->next;	
	tmp->next = pa;			
	
	return TRUE;
}

//刪除數據(按位置)
BOOL delete_index(List *ls,int index)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(ls->head == tmp || ls->head == tmp->next)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;
	free(p);
	
	return TRUE;
}

//刪除數據(按數據)
BOOL delete_pos(List *ls,Data data)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next !=ls->head)
	{
		if(tmp->next->data == data)
		{
			Node *p = tmp->next;
			tmp->next = p->next;
			free(p);
			return TRUE;
		}
		tmp = tmp->next;
	}
	return FALSE;
}

//逆序
BOOL Reverse(List *ls)
{
	if(NULL == ls || NULL == ls->head)
		return ERROR;
	
	if(ls->head == ls->head->next)
	{
		printf("鏈表爲空\n");
		return FALSE;
	}
	if(ls->head == ls->head->next->next)
	{
		printf("鏈表只有1個無需逆序\n");
		return FALSE;
	}
		
	Node *pre = ls->head->next;			//第一個結點
	Node *cur = pre->next;				//要換的結點
	Node *tmp;							//保存指向下一個地址
	
	while(cur != ls->head)
	{
		tmp = cur->next;
		cur->next = pre;
		
		pre = cur;
		cur = tmp;
	}
	
	ls->head->next->next = ls->head;
	ls->head->next = pre;
	
	return TRUE;
}


//打印
void Display(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head->next;
	while(tmp != ls->head)
	{
		printf("%-4d",tmp->data);
		tmp = tmp->next;
	}
	printf("\n");
}

//刪除鏈表
void Destroy(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next != ls->head)
	{	
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

三、雙向循環鏈表

將雙向鏈表改成循環鏈表的技巧
(1)將雙向鏈表中的一些NULL改成ls->head。
(2)去除最後一個結點是否是NULL的判斷

#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>

List *Creat()
{	
	List *ls = (List *)malloc(sizeof(List)/sizeof(char));
	if(NULL == ls)
		return NULL;
	
	ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = ls->head;
	ls->head->pre  = ls->head;
	return ls;
}

//頭插
BOOL inster_head(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = ls->head->next;
	pa->pre  = ls->head;
	ls->head->next = pa;
	pa->next->pre  = pa; 

	return TRUE;
}

//尾插
BOOL inster_last(List *ls,Data data)
{
	if(NULL == ls)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	
	if(NULL == pa)
		return ERROR;
	
	pa->data = data;
	pa->next = ls->head;
	
	Node *tmp = ls->head;
	while(tmp->next != ls->head)
	{
		tmp = tmp->next;
	}
	tmp->next = pa;
	pa->pre   = tmp;
	
	return TRUE;
}

//鏈表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
	if(NULL == ls || index < 1)
		return ERROR;
	
	Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
	if(NULL == pa)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(tmp == ls->head)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	pa->data = data;		//要插入的數據
	pa->next = tmp->next;	
	pa->pre  = tmp;
	tmp->next = pa;		
	pa->next->pre = pa;
	
	return TRUE;
}

//刪除數據(按位置)
BOOL delete_index(List *ls,int index)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	int i;
	for(i = 0; i < index-1; i++)
	{
		tmp = tmp->next;
		if(ls->head == tmp || ls->head == tmp->next)
		{
			printf("鏈表越界,長度=%d\n",index);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;
	p->next->pre = tmp;
	free(p);
	
	return TRUE;
}

//刪除數據(按數據)
BOOL delete_pos(List *ls,Data data)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next != ls->head)
	{
		if(tmp->next->data == data)
		{	
			Node *p = tmp->next;
			tmp->next = p->next;
			p->next->pre = tmp;
			free(p);
			return TRUE;
		}
		tmp = tmp->next;
	}
	return FALSE;
}

//逆序
BOOL Reverse(List *ls)
{
	if(NULL == ls || NULL == ls->head)
		return ERROR;
	
	if(ls->head == ls->head->next)
	{
		printf("鏈表爲空\n");
		return FALSE;
	}
	if(ls->head == ls->head->next->next)
	{
		printf("鏈表只有1個無需逆序\n");
		return FALSE;
	}
		
	Node *cur = ls->head->next;			//第一個結點
	
	while(cur != ls->head)
	{
		Node *tmp = cur->next;			//保存指向下一個地址
		cur->next = cur->pre;
		cur->pre  = tmp;
		
		cur = tmp;
	}
		Node *tmp = cur->next;			
		cur->next = cur->pre;
		cur->pre  = tmp;
	
	return TRUE;
}

//打印
void Display(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head->next;
	while(tmp != ls->head)
	{
		printf("%-4d",tmp->data);
		tmp = tmp->next;
	}
	printf("\n");
}

//刪除鏈表
void Destroy(List *ls)
{
	if(NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while(tmp->next != ls->head)
	{	
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章