数据结构第五天

一、双向链表

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章