单链表的基本操作(增删改查)

对于单链表的创建上篇文章我们已经写过了,但是在这还为大家展示一下尾插法创建链表:

首先定义一个头指针,接下来为新的节点开辟空间,并让头指针等于它:

 接下来创建新的节点并让前一个节点变为旧的结点,并让旧节点中的指针指向新节点

 然后就是不断重复上述第二步。

struct notes
{
    int n;
    struct notes *next;
};

int cnt;//定义一个整型变量用来计算结点的数量

struct notes*create() 
{
	struct notes *pnew,*pend;
    struct notes *phead=NULL;//让头指针指向为空。
	cnt = 0;
 
	pnew = pend = (struct notes*)malloc(sizeof (struct notes));
	scanf("%d",&pnew->n );//输入第一个元素
 
	while(pnew->n != 0){
 
		cnt++;
 
		if(cnt == 1){
			pnew->next = phead;//让第一个元素的下一个节点指向为空
			pend = pnew;//让旧结点等于新的结点
			phead = pnew;//让头指针指向第一个结点
		}else{
			pnew->next = NULL;
			pend->next = pnew;//让上一个结点指向下一个结点
			pend = pnew;
		}
		pnew=(struct notes*)malloc(sizeof(struct notes));
		scanf("%d",&pnew->n );
	}
 
	free(pnew);//释放数据为零的空间
	
	return phead;//返回头指针
}

//创建函数用来遍历链表
void print(struct notes*phead)
{
	struct notes *ptemp;//定义一个临时指针用来输出元素
	ptemp = phead;//让临时指针等于头指针
//开始循环输出
	while(ptemp != NULL){
		printf("%d\n",ptemp->n );
		ptemp = ptemp->next ;//让元素自身等于它指向的下一个元素
	}
}

链表的创建与遍历就到此为止了,接下来就是链表其他的基础操作。

1,链表的插入(增);

(1)在链表头部插入新节点:

struct notes *SListPushFront(struct notes *phead)
{
 	struct notes *pnew;//定义需要插入的节点

 	pnew=(struct notes*)malloc(sizeof(struct notes));//开辟空间

 	scanf("%d",&pnew->n );//输入新值

 	pnew->next = phead;//让新节点指向原来的头结点

 	phead=pnew;//让头结点等于新插入的结点
 	return phead;//返回新节点
 } 

(2)在链表的第k个值前插入:

在第k个值前插入首先得让链表进行遍历并让遍历在第k个值时停止。

void AddListbeforek(struct notes *phead)
{
    int k;
    scanf("%d",&k);//输入k的值。
    struct notes *pnew;
    pnew = (struct notes*)malloc(sizeof(struct notes));
    scanf("%d",&pnew->n);
    int i;
    struct notes *p;//创建临时结点,用来存储第k-1个结点。
	struct notes *ptemp;//创建一个临时结点用来遍历第k个结点之前的元素。 
    for(i=1;i<=k;i++){
    	p = ptemp;//让p等于当前ptemp的结点 。 
    	ptemp = ptemp->next;//当循环停止时,ptemp刚好为第k个结点。 
	}
	p->next = pnew;//让原来第k-1个结点指向新结点。 
	pnew->next = ptemp; //让新节点指向第k个结点。
 } 

当然,在头部插入和在第k个值前插入是可以在一个函数里完成的,但是函数类型就变为了结构体指针类型了,需要返回其头指针。

struct notes *AddListbeforek(struct notes *phead)
{
	int k;
	scanf("%d",&k);
    struct notes *pnew;
    pnew = (struct notes*)malloc(sizeof(struct notes));
    scanf("%d",&pnew->n);
    //判断k是否等于1。 
    if(k==1){
    	pnew->next = phead;
    	phead = pnew;
    	return phead;
	}
	//如果不等于1,进行接下来的步骤。 
    int i;
    struct notes *p;//创建临时结点,用来存储第k-1个结点。
	struct notes *ptemp;//创建一个临时结点用来遍历第k个结点之前的元素。 
    for(i=1;i<=k;i++){
    	p = ptemp;//让p等于当前ptemp的结点 。 
    	ptemp = ptemp->next;//当循环停止时,ptemp刚好为第k个结点。 
	}
	p->next = pnew;//让原来第k-1个结点指向新结点。 
	pnew->next = ptemp; //让新节点指向第k个结点。
	return phead;
 } 

(3)在尾部插入新结点,需要链表遍历至最后一个结点。

void PushBack(struct notes *phead)
{
	struct notes *pnew;
	pnew = (struct notes *)malloc(sizeof(struct notes));
	scanf("%d",&pnew->n);
	pnew->next = NULL;//让新结点的指向为空 
	struct notes *ptemp;//创建临时结点,用来遍历至尾结点。 
	ptemp = phead;
	while(ptemp->next = NULL){//当遍历至尾结点时停止 
		ptemp = ptemp->next;
	}
	ptemp->next = pnew;//让原来的尾结点指向加入的结点,使新节点变为尾结点。 
}

2,删除指定结点,也需要遍历至k结点,并让k-1指向k+1。

如:删除第k个结点:

node *DeleteListTail(node *phead)
{
	node *ptemp;//临时结点,用来遍历链表。
	ptemp = phead;
	int k;
	scanf("%d",&k);//输入k的值。
	if(k==1){//如果删除第一个结点,则执行。 
		phead = ptemp->next;
		free(ptemp);
		return phead;
	}
	
	int i=1;
	node *l;//临时结点,用来存储k-1的元素。 
	while(i!=k){
		l = ptemp;
		ptemp = ptemp->next;
		i++;
	}
	
	if(ptemp->next == NULL){//判断是否删除最后一个节点 
		free(ptemp);
		l->next = NULL;
		return phead;//返回第k-1个结点。 
	} 
	
	l->next = ptemp->next;//让k-1指向k+1。 
	free(ptemp);//释放第k个结点的空间。 
	return phead; 
}

3.改变第k个结点的值。

void gai(node *phead)
{
	node *ptemp;
	ptemp = phead;
	int i=1,k;
	scanf("%d",&k);
	while(i!=k){
		ptemp = ptemp->next;
	}
	scanf("%d",&ptemp->n);
}

4,查询第k个结点;

和改变某一节点的值相似,但是没有输入结点元素值的部分。

void gai(node *phead)
{
	node *ptemp;
	ptemp = phead;
	int i=1,k;
	scanf("%d",&k);
	while(i!=k){
		ptemp = ptemp->next;
	}
	printf("%d",ptemp->n);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值