数据结构之单向链表

文章目录

  • 链表
    • 单向链表
      • C实现单向链表
      • .h文件
      • .c文件

链表

结构体+指针 ===> 更强大的数据结构

链表由多个节点链接而成
节点的组成:
1、数据域 : 存储数据
2、指针域 : 指向关联的节点

单向链表

分类:
1、头指针式链表 ====> 不实用很麻烦
2、头结点式链表 ====> 常用

数据结构之单向链表_第1张图片

节点:
Typedef int Data;
Typedef struct _node
{
​ Data data;
​ struct _node *next;
}Node;
Typedef struct _list
{
​ Node *head;
}List;

数据结构之单向链表_第2张图片

数据结构之单向链表_第3张图片

常用操作:

1 创建
2 摧毁
3 增加
4 删除
5 查找
6 修改
7 逆序

C实现单向链表

.h文件

#ifndef  _LINKLIST_H_
#define  _LINKLIST_H_

typedef enum {TRUE,FALSE,ERROR} Bool;

typedef int Data;

typedef struct _node
{
	Data  data ;             //存储数据
	struct _node   *next;   // 指向下一个节点
}Node;

typedef struct _list
{
	Node *head;  //指向头结点;
}List;



//创建空链表
List* Creat ();

//摧毁链表
//[in]list  : 需要摧毁的链表
void destroy(List*list);


//插入数据:头插
// [in]list  : 要插入的单链表
// [in]data  : 要插入的数据
Bool Insert_Head(List*list,Data data);

//插入数据:尾插
// [in]list  : 要插入的单链表
// [in]data  : 要插入的数据
Bool Insert_Tail(List*list,Data data);

//插入数据:	按位置插入
// [in]list  : 要插入的单链表
// [in]pos  : 要插入的位置
// [in]data  : 要插入的数据
Bool Insert_Pos(List*list,int pos,Data data);


//删除数据:	按位置删除
// [in]list  : 要插入的单链表
// [in]pos  : 要插入的位置
Bool Delete_Pos(List*list,int pos);


//删除数据:	按数据删除
// [in]list  : 要插入的单链表
// [in]data  : 要插入的数据
Bool Delete_Data(List*list,Data data);


//单向链表逆序
Bool Reverse(List *list);

//打印
void Display(List*list);

#endif  // _LINKLIST_H_

.c文件

#include 
#include 
#include "linklist.h"

//创建空链表
List* Creat ()
{
	List *list = (List*)malloc(sizeof(List)/sizeof(char));
	if(NULL ==list)
	{
		return NULL ;
	}

	list->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == list->head )
	{
		free(list);
		return NULL;
	}

	list->head->next =NULL;
	return list;
}

//摧毁链表
void destroy(List*list)
{
	if(list == NULL)
		return ;

	Node *tmp = list->head->next; //指向第一个节点

	while(tmp != NULL)
	{
		Node *p   = tmp;
		tmp = tmp ->next;
		free(p);
	}

	free(list->head );
	free(list);

}

Bool Insert_Head(List*list,Data data)
{
	if(NULL == list)
		return ERROR;

	Node * new_node= (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == new_node)
	{
		return FALSE;
	}
	new_node ->data  = data;
	new_node ->next  = list->head->next;
	list->head->next = new_node;

	return TRUE;
}

Bool Insert_Tail(List*list,Data data)
{
	if(NULL == list)
		return ERROR;

	Node * new_node= (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == new_node)
	{
		return FALSE;
	}

	new_node ->data = data;
	new_node ->next = NULL;

	//找到最后指向空的节点
	Node *tmp = list->head;  //指向头结点
	while(tmp->next)
	{
		tmp = tmp->next;
	}
	tmp->next =new_node;

	return TRUE;
}

Bool Insert_Pos(List*list,int pos,Data data)
{

	if(NULL == list || pos <1)
		return ERROR;

	Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == node)
	{
		return FALSE;
	}

	Node *tmp =list->head;  //指向头结点

	//找到指点位置的插入的前一个节点
	int i;
	for(i=0;i<pos-1;i++)
	{
		tmp = tmp->next;
		if(NULL == tmp)
		{
			printf("%d的位置已越界\n",pos);
			return ERROR;
		}
	}

	node->next = tmp->next;
	tmp->next  = node;
	node->data = data;





	return TRUE;
}

Bool Delete_Pos(List*list,int pos)
{
	if(NULL == list || pos<1)
		return ERROR;


	Node *tmp = list->head;//指向头结点


	int i;
	for(i=0;i<pos-1;i++)
	{
		tmp =tmp->next;
		if(NULL == tmp->next)
		{
			printf("%d的位置已经越界\n",pos);
			return ERROR;
		}
	}

	Node *pos_node =tmp->next;
	tmp->next =pos_node->next;
	free(pos_node);

	return TRUE;
}

Bool Delete_Data(List*list,Data data)
{

	if(NULL == list )
		return ERROR;

	Node *tmp =list->head;

	while (tmp->next)
	{
		if (tmp->next->data == data)
		{
			Node *cur = tmp->next;
			tmp->next = p->next;
			free(cur);

			return TRUE;
		}
		tmp = tmp->next;
	}
	return FALSE;
}

Bool Reverse(List *list)
{

	// NULL == list || NULL == list->head || NULL == list->head->next  空链表
	// NULL == list->head->next->next   只有一个节点
	if(NULL == list || NULL == list->head || NULL == list->head->next|| NULL == list->head->next->next)
		return ERROR;

	Node *pre =list->head->next; //逆序的前一个节点
	Node *cur =pre->next;		 //逆序的当前节点
	Node *tmp;		//保存当前逆序节点的后一个节点

	while(cur != NULL)
	{
		tmp 	  = cur->next;  //保存当前逆序节点的后一个节点
		cur->next = pre;		//指向前一个节点

		//后移一步
		pre       = cur;
		cur		  = tmp;
	}
	//逆序后的最后一个节点指向NULL
	list->head->next->next = NULL;

	//头结点指向逆序后的第一个节点
	list->head->next       = pre;

	return TRUE;
}

void Display(List*list)
{
	//
	if(NULL == list)
		return ;

	Node *tmp = list->head->next;  //指向第一个节点
	while(tmp)
	{
		printf("%-4d",tmp->data);
		tmp = tmp->next;
	}
	printf("\n");
}

你可能感兴趣的:(数据结构与算法基础知识)