数据结构之链表


前言

本文记录的是链表的一些操作,例如链表的创建、排序、删除、求链表的长度、判断链表是否为空。以下内容是根据郝斌老师教导所写的代码。


一、代码

代码仅供参考,若有不足的地方,欢迎在评论区一起讨论。

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

typedef struct Node{
	int data;										//数据
	struct Node* pNext;								//指向下一个结点
}NODE, *PNODE;										//NODE 等价于 struct Node, PNODE 等价于 struct Node*

PNODE CreateList();									//创建链表,返回值是一个头结点指针
void TraverseList(PNODE head);						//遍历链表
bool Is_Empty( PNODE phead );						//判断链表是否为空
int Length_List( PNODE phead );						//求链表的长度
void Sort_List( PNODE phead );						//链表排序
bool Insert_List(PNODE phead, int pos, int val );	//链表在pos位置前插入新元素,pos是从1开始的
bool Delete_List(PNODE phead, int pos, int* val);	//删除pos位置的节点,pos从1开始i


int main(void) {
	int val, pos;
	PNODE phead = NULL;				//头结点先指向空
	phead = (PNODE)malloc( sizeof( NODE ) );
	if( NULL == phead ) {
		printf("创建链表失败!\n");
		exit(-1);
	}

	phead = CreateList();			//phead得到创建链表的头结点
	printf("该链表是:");
	TraverseList(phead);			//遍历链表
	

	if( Is_Empty( phead ) ) {
		printf("该链表为空\n");
	} else {
		printf("该链表不为空\n");
	}


	int len = Length_List( phead );
	printf("链表的长度是:%d\n", len);

	printf("该链表排序后:");
	Sort_List( phead );
	TraverseList(phead);			//遍历链表
	printf("\n");

	printf("请输入您想要在哪个位置前插入节点和插入节点的值:");
	scanf("%d,%d", &pos, &val);
	printf("\n");
	Insert_List(phead, pos, val);
	printf("插入后链表变成:");
	TraverseList(phead);			//遍历链表

	if(Delete_List(phead, 5, &val) ) {
		printf("删除链表第五个节点成功!\n");
	}
	printf("删除后链表为:");
	TraverseList(phead);			//遍历链表
	printf("\n");

	return 0;
}

//尾插法
PNODE CreateList(){
	int len, val, i;				//len是链表的长度,val是节点的值
	PNODE phead = NULL;				//头结点先指向空

	phead = (PNODE)malloc( sizeof( NODE ) );
	if( NULL == phead ) {
		printf("创建链表失败!\n");
		exit(-1);
	}
	
	PNODE ptail = phead;
	ptail->pNext = NULL;			//有可能一个节点都没有

	printf("请输入您要创建多少个节点的链表:");

	scanf("%d", &len);

	for( i = 0; i < len; i++ ) {
		printf("请输入第%d个节点的值:", i + 1);
		scanf("%d", &val);

		PNODE pnew;
		pnew = (PNODE)malloc( sizeof(NODE) );
		if( NULL == pnew ){
			printf("创建新节点失败!\n");
			exit(-1);
		}
		pnew->data = val;

		ptail->pNext = pnew;
		pnew->pNext = NULL;
		ptail = pnew; 
	}

	return phead;
}

//遍历链表
void TraverseList(PNODE phead){
	PNODE p;
	p = phead->pNext;
	while( NULL != p ){
		printf("%d ", p->data);
		p = p->pNext;	
	}
	printf("\n");
}

//判断链表是否为空
bool Is_Empty( PNODE phead ) {
	if( NULL == phead ) {
		return true;
	} else {
		return false;
	}
}

//求链表的长度
int Length_List( PNODE phead ) {
	PNODE p = phead->pNext;
	int len = 0;
	while( NULL != p ) {
		len++;
		p = p->pNext;
	}

	return len;

}


//链表的由小到大排序(冒泡法)
void Sort_List( PNODE phead ) {
	int i, j, temp, len;
	len = Length_List(phead);
	PNODE p, q;
	for( j = 0, p = phead->pNext; j < len-1; j++, p = p->pNext) {
		for( i = 0, q = phead->pNext; i < (len-1)-j; i++ , q = q->pNext ){
			if( q->data  > q->pNext->data ){
				temp = q->data;
				q->data = q->pNext->data;
				q->pNext->data = temp;
			}	
		}
	}


	return ;
}

//链表的插入,在phead所指向的链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且的pos的值是从1开始
bool Insert_List(PNODE phead, int pos, int val ) {
	int i = 0;
	PNODE p = phead;
	

	//让p指向链表的pos位置的前一个节点
	while( (NULL != p) && (i < pos-1) ) {
		p = p->pNext;	//指向下一个节点
		i++;
	}
	
	if( (i > pos-1) || (NULL == p) ) {
		return false;
	}

	PNODE pnew = (PNODE)malloc( sizeof(NODE) );
	if( NULL == pnew) {
		printf("创建新节点失败!\n");
		exit(-1);
	}
	pnew->data = val;

	PNODE q = p->pNext;	//此时p指向第pos个节点的前一个节点,q指向p的下一个节点
	p->pNext = pnew;
	pnew->pNext = q;

	return true;

}

//删除pos位置的节点,pos从1开始
bool Delete_List(PNODE phead, int pos, int* val) {
	int i = 0;
	PNODE p = phead;
	
	//让p指向链表pos的前一个节点
	while( (NULL != p->pNext) && (i < pos-1) ) {
		i++;
		p = p->pNext;
	}
	
	
	if( (i > pos-1) || (NULL == p->pNext) ) {
		return false;
	}

	PNODE q = p->pNext;
	*val = q->data;
	printf("被删除的节点的值是:%d\n", *val);

	//删除p节点的后一个节点
	p->pNext = p->pNext->pNext;
	free(q);
	q = NULL;

	return true;
}

二、结果所示

在这里插入图片描述

总结

一些基本算法需要不断在用笔在纸上不断画图推敲,验证自己所写的代码是否有误。学习数据结构,光看伪算法而不上机操作是无法提升水平。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

free(me)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值