C -- linked_list

本文详细介绍了链表的数据结构,包括结点定义、链表类型的创建、添加、查找、删除及清空链表的操作方法。同时,提供了使用C语言实现链表的代码示例,以及如何封装链表操作为独立函数,方便进行链表的管理和维护。

链表(Linked List

  1. 定义结点类型,链表的基本单元:
typedef struct _node
{
	int value;
	struct _node * next;
}Node;
  1. 定义列表类型,存放链表头结点指针和尾结点指针,表示一个链表类型:
typedef struct _list
{
	Node * head;
	Node * tail;
}List;
  1. 声明一个结点基本单元并初始化
Node * p = (Node *) malloc (sizeof(Node));	
p->value = number;		
p->next = null;		
  1. 声明一个链表并初始化头尾指针
List list;
list.head = list.tail = NULL;
  1. 将新结点链接到list(Linked_list)上
//如果此时链表头为空,即开始添加刚申请到并初始化完成的第一个结点
if(list.head == NULL)		
	list.head = list.tail = p;
//否则则代表链表中已存在结点,将先前tail->next指向新申请到的p,完成链接新结点
else
{
	list.tail->next = p;
	list.tail = p;
}

通过以上五个步骤便已经完成了创建链表(linked_list)

关于链表的其他操作(查找、删除、清除

  1. 如何查找链表中相应元素,即如何遍历
Node * p;
for(p = list.head;p;p = p->next)
{
	if(p->value == number)
	{
		printf("Found!\n");
		break;
	}
}
  1. 删除链表指定元素,查找到删除当前位置,让前一个链接到后一个结点,注意删除头结点情况
Node *p,*q;
for(q = NULL,p = list.head;p;q = p,p = p->next)
	if(number == p->value)
		if(q == NULL)
		{
			list.head = p->next;
			break;
		}
		else
		{
			q->next = p->next;
			free(p);
			break;
		}
  1. 清除整个链表
Node *p,*q;
for(p = list.head;p;p = q)
{
	q = p->next;
	free(p);
}

以上是关于链表的常见操作(查找、删除、清除)的方法;

重点:关于封装的方法

需要注意的三点:

  1. 函数基于已定义的结点、链表类型
  2. 函数的接口采用指向链表的指针,便于修改链表
  3. 此处仅演示创建链表类型,传递链表指针处理的方法

优点:基于我们自己定义的List类型我们可以创建一系列的链表,并用各种函数处理单个链表,相当于有了一个链表的完整体系。

  1. 定义结点以及链表类型
//定义结点,链表的基本单元
typedef struct _node
{
	int value;
	struct _node * next;
}Node;

//定义链表类型,存放链表头结点指针和尾结点指针
typedef struct _list
{
	Node * head;
	Node * tail;
}List;

//声明一个链表
List list;
  1. 添加新结点的函数.
    函数原型: void add_to_list(List * ls, int num);
void add_to_list(List * ls, int num)
{
	Node * p = (Node *) malloc (sizeof(Node));	
	p->value = num;		
	p->next = null;		

	if(ls->head == NULL)
		ls->head = ls->tail = p;
	else
	{
		ls->tail->next = p;
		ls->tail = p;
	}
}
  1. 查找元素的函数.
    函数原型: void find_in_list(List * ls, int num);
void find_in_list(List * ls, int num)
{
	Node * p;
	bool isfound = false;

	for(p = ls->head;p;p = p->next)
		if(p->value == num)
		{
			isfound = true;
			break;
		}
	if(isfound)
		printf("Found!\n");
	else
		printf("Not Found!\n");
}
  1. 删除指定元素的函数
    函数原型: void del_a_num(List * ls, int num);
void del_a_num(List * ls, int num)
{
	Node *p, *q;
	for(q = NULL,p = ls->head;p;q=p, p = p->next)
		if(num == p->value)
		{
			if(q == NULL)
			{
				ls->head = p->next;
				break;
			}else
			{
				q->next = p->next;
				free(p);
				break;
			}
		}
}
  1. 清除整个链表的函数
    函数原型: void del_linked_list(List * ls);
void del_linked_list(List * ls)
{
	Node *p,*q;
	for(p = ls->head;p;p = q)
	{
		q = p->next;
		free(p);
	}
}

建立ADT并实现接口练习

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

//假设我们要做一个存放int类型值的一个链表,并开发建立接口

/* 第一步,建立抽象数据类型(ADT)	*/
//定义结点类型
typedef struct _node
{
	int value;
	struct _node * next;
}Node;
//定义链表类型,最终抽象出的ADT
typedef struct _list
{
	Node * head;
	Node * tail;
}List;

/* 第二步,抽象接口				*/
void add(List * ls, int val);//添加一个新项	
bool is_empty(const List * ls);//确定链表是否为空
bool is_full(const List * ls);//确定链表是否已满,遍历检查
int count(const List * ls);//确定链表项数
void show(const List * ls);//访问链表每一项,显示
void insert(List * ls, int index, int val);//链表中任意位置插入一个项
void remove(List * ls, int val);//移除链表中的一个项
bool found(const List * ls, int val);//在链表中检索一个项(不改变链表)
void change(List * ls, int index, int val);//用另一个项替换链表中的一个项
int research(const List * ls, int val);//链表中搜索一个项目,返回位置,-1表示未找到
void clear(List * ls);//清空整个链表

/* 第三步,实现接口		*/	
void add(List * ls, int val)
{
	Node * p = (Node *) malloc (sizeof(Node));
	p->value = val;
	p->next = NULL;

	//第一个结点
	if(ls->head == NULL)
		ls->head = ls->tail = p;
	else 		//后续结点
	{
		ls->tail->next = p;
		ls->tail = p;
	}
}

bool is_empty(const List * ls)
{
	bool ret = false;

	if(ls->head == NULL && ls->tail == NULL)
		ret = true;

	return ret;
}

bool is_full(const List * ls)
{
	bool ret = true;

	Node * p;
	for(p = ls->head;p;p = p->next)
		if(&(p->value) == NULL)
		{
			ret = false;
			break;
		}

		return ret;
}

int count(const List * ls)
{
	int cnt = 0;

	Node * p;
	for(p = ls->head;p;p = p->next)
		cnt++;

	return cnt;
}

void show(const List * ls)
{
	Node * p;
	for(p = ls->head;p;p = p->next)
		printf("%d ",p->value);
	putchar('\n');
}

void insert(List * ls, int index, int val)
{
	int i = 0;
	Node * new = (Node *) malloc (sizeof(Node));
	new->value = val;

	Node * p, * q;
	for(q = NULL, p = ls->head;p;q = p, p = p->next,i++)
	{
		//插在第一个
		if(index == 0)
		{
			new->next = ls->head;
			ls->head = new;
			break;
		//插在最后一个
		}else if (index == count(ls)) {
			new->next = NULL;
			ls->tail->next = new;
			ls->tail = new;
			break;
		//插在中间
		}else if (index == i) {
			q->next = new;
			new->next = p;
			break;
		}
	}
}

void remove(List * ls, int val)
{
	Node *p, *q;
	for(q = NULL, p = ls->head;p;q = p, p = p->next)
		if(p->value == val)
		{
			//删除的是第一个
			if(q == NULL)
			{
				ls->head = p->next;
				free(p);
				break;
			}else
			{
				q->next = p->next;
				free(p);
				break;
			}
		}
}

bool found(const List * ls, int val)
{
	bool ret = false;

	Node * p;
	for(p = ls->head;p;p = p->next)
		if(p->value == val)
			ret = true;
	
	return ret;
}

void change(List * ls, int index, int val)
{
	int i = 0;
	Node * p;
	for(p = ls->head;p;p = p->next, i++)
		if(i == index)
		{
			p->value = val;
			break;
		}
}

int research(const List * ls, int val)
{
	int ret = -1;
	int index = 0;
	Node * p;
	for(p = ls->head;p;p = p->next, index++)
		if(p->value == val)
		{
			ret = index;
			break;
		}

		return ret;
}

void clear(List * ls)
{
	Node *q, *p;
	for(p = ls->head;p;p = q)
	{
		q = p->next;
		free(p);
	}
}

驱动测试以上接口

测试接口


2019.12.7
修炼之路(一)
未完待续
归期不定
by lx

#include "linked_list.h" linked_list_ptr LINKED_LIST_CREATE () { linked_list_ptr linked_list_ptr_H = NULL; if (NULL == (linked_list_ptr_H = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return linked_list_ptr_H; } memset (&(linked_list_ptr_H->data), 'H', sizeof (linked_list_ptr_H->data)); linked_list_ptr_H->next = NULL; return linked_list_ptr_H; } int LINKED_LIST_FREE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != (linked_list_ptr_node = linked_list_ptr_node->next)) { free (linked_list_ptr_H); num ++; linked_list_ptr_H = linked_list_ptr_node; } free (linked_list_ptr_H); num ++; return num; } int LINKED_LIST_COUNT (linked_list_ptr linked_list_ptr_H) { int num = -1; while (NULL != linked_list_ptr_H) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } return num; } int LINKED_LIST_INSERT (linked_list_ptr linked_list_ptr_H, data_t data, int pos) { if (NULL == linked_list_ptr_H) { return -1; } int num = 0; if (-1 == pos) { while (NULL != linked_list_ptr_H->next) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = NULL; } else { while (NULL != linked_list_ptr_H->next && 0 != pos --) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == linked_list_ptr_H->next) { if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = NULL; } else { linked_list_ptr linked_list_ptr_node = linked_list_ptr_H->next; if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = linked_list_ptr_node; } } return num; } int LINKED_LIST_DELETE (linked_list_ptr linked_list_ptr_H, int pos) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return -2; } int num = 0; if (-1 == pos) { while (NULL != linked_list_ptr_H->next->next) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } free (linked_list_ptr_H->next); linked_list_ptr_H->next = NULL; } else { while (NULL != linked_list_ptr_H->next->next && 0 != pos --) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == linked_list_ptr_H->next->next) { free (linked_list_ptr_H->next); linked_list_ptr_H->next = NULL; } else { linked_list_ptr linked_list_ptr_node = linked_list_ptr_H->next->next; free (linked_list_ptr_H->next); linked_list_ptr_H->next = linked_list_ptr_node; } } return num; } int LINKED_LIST_PURGE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return 0; } if (NULL == linked_list_ptr_H->next->next) { return 1; } int num = 2; linked_list_ptr linked_list_ptr_node1 = NULL, linked_list_ptr_node2 = NULL; while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next)->next->next) { linked_list_ptr_node1 = linked_list_ptr_H; while (NULL != linked_list_ptr_node1->next->next) { if (linked_list_ptr_H->data == linked_list_ptr_node1->next->data) { linked_list_ptr_node2 = linked_list_ptr_node1->next->next; free (linked_list_ptr_node1->next); linked_list_ptr_node1->next = linked_list_ptr_node2; continue; } linked_list_ptr_node1 = linked_list_ptr_node1->next; } if (linked_list_ptr_H->data == linked_list_ptr_node1->next->data) { free (linked_list_ptr_node1->next); linked_list_ptr_node1->next =NULL; } num ++; } return num; } linked_list_ptr LINKED_LIST_LOCATE_NUM2ADD (linked_list_ptr linked_list_ptr_H, int pos) { if (NULL == linked_list_ptr_H) { return NULL; } if (NULL == linked_list_ptr_H->next) { return NULL; } if (-1 == pos) { while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next)->next); } else { while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next) && 0 != pos --); } return linked_list_ptr_H; } int LINKED_LIST_LOCATE_ADD2NUM (linked_list_ptr linked_list_ptr_H, linked_list_ptr linked_list_ptr_node) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_node) { return -2; } if (linked_list_ptr_H == linked_list_ptr_node) { return -3; } if (NULL == linked_list_ptr_H->next) { return -4; } int num = 0; while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next) && linked_list_ptr_node != linked_list_ptr_H) { num ++; } if (linked_list_ptr_H != linked_list_ptr_node) { return -5; } return num; } int LINKED_LIST_REVERSE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return 0; } if (NULL == linked_list_ptr_H->next->next) { return 1; } int num = 2; linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next, linked_list_ptr_node3 = linked_list_ptr_H->next->next->next; linked_list_ptr_node1->next = NULL; while (NULL != linked_list_ptr_node3) { linked_list_ptr_node2->next = linked_list_ptr_node1; linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node3; linked_list_ptr_node3 = linked_list_ptr_node3->next; num ++; } linked_list_ptr_node2->next = linked_list_ptr_node1; linked_list_ptr_H->next = linked_list_ptr_node2; return num; } int LINKED_LIST_BUBBLE_SORT_MIN (linked_list_ptr linked_list_ptr_H) { int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != linked_list_ptr_node) { linked_list_ptr_node = linked_list_ptr_node->next; num ++; } if (2 > num) { return num; } linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next; for (int i = 0; i < num - 1; i ++) { for (int j = 0; j < num - 1 - i; j ++) { if (linked_list_ptr_node1->data > linked_list_ptr_node2->data) { linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; linked_list_ptr_node2->data ^= linked_list_ptr_node1->data; linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; } linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node2->next; } linked_list_ptr_node1 = linked_list_ptr_H->next; linked_list_ptr_node2 = linked_list_ptr_H->next->next; } return num; } int LINKED_LIST_BUBBLE_SORT_MAX (linked_list_ptr linked_list_ptr_H) { int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != linked_list_ptr_node) { linked_list_ptr_node = linked_list_ptr_node->next; num ++; } if (2 > num) { return num; } linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next; for (int i = 0; i < num - 1; i ++) { for (int j = 0; j < num - 1 - i; j ++) { if (linked_list_ptr_node1->data < linked_list_ptr_node2->data) { linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; linked_list_ptr_node2->data ^= linked_list_ptr_node1->data; linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; } linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node2->next; } linked_list_ptr_node1 = linked_list_ptr_H->next; linked_list_ptr_node2 = linked_list_ptr_H->next->next; } return num; } int LINKED_LIST_PRINTF (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } int num = 0; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != (linked_list_ptr_node = linked_list_ptr_node->next)) { printf ("%d ", linked_list_ptr_node->data); num ++; } if (NULL != linked_list_ptr_H->next) { putchar ('\n'); } return num; } 寻找这段代码的错误
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值