数据结构与算法(2)——单链表

前言

链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。在这里使用C来学习下链表,比如:链表的创建,修改,删除,插入,输出,排序,反序,清空链表的元素,求链表的长度等等。

单链表

在这里插入图片描述

通常使用一个结构体来描述一个链表中的一个节点。

typedef int data_t;
typedef struct linklist_node{
	data_t data;
	struct linklist_node* next;
}linklist_t;

创建一个节点,使用malloc为节点分配空间

//创建
linklist_t* create_linklist()
{
	linklist_t* list=malloc(sizeof(linklist_t));
	list->next=NULL;
	return list;
}

初始化一个链表,n为链表节点个数


LinkList *creat(int n){
	LinkList *head, *node, *end;//定义头节点,普通节点,尾部节点;
	head = (LinkList*)malloc(sizeof(LinkList));//分配地址
	end = head;         //若是空链表则头尾节点一样
	for (int i = 0; i < n; i++) {
		node = (LinkList*)malloc(sizeof(LinkList));
		scanf("%d", &node->data);
		end->next = node;
		end = node;
	}
	end->next = NULL;//结束创建
	return head;
//判空
int isnull_linklist(linklist_t* list)
{
	return list->next==NULL;
}

创建一个头结点之后,插入节点,可使用前插入和后插入以及指定位置插入三种方式

在这里插入图片描述

//front insertion //这种方式不算是最头,准确来说应该是在基准节点之后插入
int insert_front_linklist(linklist_t *list,data_t data)
{
    if(list == NULL)
        return -1;
    
    linklist_t *newnode = create_linklist();

    newnode->data = data;//新节点赋值
    newnode->next = list->next;//新节点指向基准节点之后的节点

    list->next = newnode;//基准节点指向新节点

    return 0;
}

//end insertion
int insert_end_linklist(linklist_t *list,data_t data)
{
    if(list == NULL)
        return -1;

    linklist_t *newnode = malloc(sizeof(linklist_t));
    
    newnode->data = data;
    newnode->next = NULL;

    while(list->next!=NULL)
	{
		list=list->next;//移动到最后一个节点
	}
    if(list->next == NULL)
        list->next = newnode;

    return 0;
}

指定第n个节点插入

void insert(LinkList *list, int n) {
	LinkList *t = list, *in;
	int i = 0;
	while (i < n && t != NULL) {
		t = t->next;
		i++;
	}
	if (t != NULL) {
		in = (LinkList*)malloc(sizeof(LinkList));
		puts("输入要插入的值");
		scanf("%d", &in->data);
		in->next = t->next;//填充in节点的指针域,也就是说把in的指针域指向t的下一个节点
		t->next = in;//填充t节点的指针域,把t的指针域重新指向in
	}
	else {
		puts("节点不存在");
	}

//删除,从头删,这种方式不算是最头,准确来说应该是在基准节点之后删
int delete_linklist(linklist_t* list)
{
	if(list==NULL||isnull_linklist(list))
		return -1;
	linklist_t* temp=list->next;
	list->next=temp->next;
	free(temp);
	return 0;
}

指定位置删除链表的元素也就是把前节点的指针域越过要删除的节点指向下下个节点。即:p->next = q->next;然后放出q节点的空间,即free(q);
在这里插入图片描述


void delet(LinkList *list, int n) {
	LinkList *t = list, *in;
	int i = 0;
	while (i < n && t != NULL) {
		in = t;
		t = t->next;
		i++;
	}
	if (t != NULL) {
		in->next = t->next;
		free(t);
	}
	else {
		puts("节点不存在");
	}

给一个test的code,还有很多功能没有实现,还有很多考虑不周的地方,仅用学习

#include <stdlib.h>
#include <stdio.h>
typedef int data_t;
typedef struct linklist_node{
	data_t data;
	struct linklist_node* next;
}linklist_t;

//创建
linklist_t* create_linklist()
{
	linklist_t* list=malloc(sizeof(linklist_t));
	list->next=NULL;
	return list;
}
//判空
int isnull_linklist(linklist_t* list)
{
	return list->next==NULL;
}
//增加 前插入
int insert_linklist(linklist_t* list,data_t data)
{
	if(list==NULL)
		return -1;
	linklist_t* newnode=create_linklist();
	newnode->data=data;
	newnode->next=list->next;
	list->next=newnode;
	return 0;
}

//查  返回值???
linklist_t* locate_linklist(linklist_t* list,data_t data)
{
	if(isnull_linklist(list)||list==NULL)
		return NULL;
	while(list->next!=NULL)
	{
		if(list->next->data==data)
			return list;
		list=list->next;
	}
	return NULL;
}

//删除
int delete_linklist(linklist_t* list)
{
	if(list==NULL||isnull_linklist(list))
		return -1;
	linklist_t* temp=list->next;
	list->next=temp->next;
	free(temp);
	return 0;
}

//改
int change_index_linklist(linklist_t* list,data_t data)
{
	if(isnull_linklist(list)||list==NULL)
			return -1;
	list->next->data=data;
	return 0;
}
//指定插入
//指定删除
//清空
int clear_linklist(linklist_t* list)
{
	if(isnull_linklist(list)||list==NULL)
		return -1;
	while(!isnull_linklist(list))
	{
		delete_linklist(list);
	}
	return 0;
}
//销毁
int destroy_linklist(linklist_t* list)
{
	if(list==NULL)
		return -1;
	if(!isnull_linklist(list))
		clear_linklist(list);
	free(list);
	return 0;

}

//判断长度
int length_linklist(linklist_t* list)
{
	if(isnull_linklist(list)||list==NULL)
		return 0;
	int i=0;
	while(list->next!=NULL)
	{
		i++;
		list=list->next;
	}
//	printf("\n");
	return i;
}

//逆打印1
int re_print_linklist(linklist_t* list)
{
	if(isnull_linklist(list)||list==NULL)
		return -1;
	linklist_t* temp=create_linklist();
	while(list->next!=NULL)
	{
	//	printf("%2d ",list->next->data);
		insert_linklist(temp,list->next->data);
		list=list->next;
	}
//	printf("\n");
//
	print_linklist(temp);
	destroy_linklist(temp);
	return 0;
}
//逆打印2
void re2_print_linklist(linklist_t* list)
{
	if(list->next==NULL)
		return ;
	re2_print_linklist(list->next);
	printf("%2d ",list->next->data);
	return ;
}

//打印
int print_linklist(linklist_t* list)
{
	if(isnull_linklist(list)||list==NULL)
		return -1;
	while(list->next!=NULL)
	{
		printf("%2d ",list->next->data);
		list=list->next;
	}
	printf("\n");
	return 0;
}

int main(int argc, const char *argv[])
{
	linklist_t* list=create_linklist();
	int i;
	for(i=1;i<=20;i++)
	{
		insert_linklist(list,i);
		print_linklist(list);
	}
#if 0
	for(i=1;i<=20;i++)
	{
		delete_linklist(list);
		print_linklist(list);
	}
#endif

	change_index_linklist(locate_linklist(list,14),1414);
	print_linklist(list);
	delete_linklist(locate_linklist(list,1414));
	print_linklist(list);
	insert_linklist(locate_linklist(list,1515),1616);
	print_linklist(list);
	printf("length_linklist:%d\n",length_linklist(list));

	re_print_linklist(list);
	re2_print_linklist(list);

	printf("\n");
	clear_linklist(list);
	printf("length_linklist:%d\n",length_linklist(list));
	destroy_linklist(list);
	return 0;
}

未完待续……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linux顿悟吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值