数据结构之单链表

简介

链表是一种非常常见的数据结构,主要用来对复杂的数据集进行数据的增删改查,其优点也是插入删除速度快;内存利用率高,不会浪费内存大小没有固定,拓展很灵活。

单链表代码实现

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
struct node
{
	ElemType data;
	struct node *next;
};
/*
	根据用户的输入,
	创建一个单链表
*/
struct node *create_list()
{
	int d;
	struct node *first = NULL; //指向链表的第一个结点
	struct node *last = NULL;//指向链表的最后一个结点
	struct node *p = NULL;// 指向新创建的结点
	while (1)
	{
  scanf("%d", &d);
  if (d == 0)
  {
  	break;
  }
  /*
  step 1: 创建一个新结点,保存数据
  */
  p = malloc(sizeof(*p));
  p->data = d;
  p->next = NULL;
 
  /*
  step 2: 把新创建的结点,加入到链表中去
  */
  if (first == NULL)
  {
  	first = p;
  	last = p;
  }
  else
  {
  	//"尾插法"
  	last->next = p;
  	last = p;
  	//"头插法"
  	//p->next = first;
  	//first = p;
  	#if 0
  	/*建立一个有序链表(升序)*/
  	struct node *r = NULL; //指向链表中第一个比p->data大的结点
  	struct node *pre = NULL;//指向链表中r前面那个结点
  	/*
  	2.1 在链表中找到第一个值比p->data
  	大的结点,代码如下:
  	*/
  	r = first;
  	while (r)
  	{
    if (r->data > p->data) //r找到啦
    {
    	break;
    }
    pre = r;
    r = r->next;
  	}
  	/*
  	2.2
  	*/
  	if (r == NULL) //现有链表中所有结点的值都比p->data要小
  	{
    //P应该是插入到最后,  
    last->next = p;
    last = p;
  	}
  	else
  	{
    if (r == first)
    {
    	//p应该插入到最前面
    	p->next = first;
    	first = p;
    }
    else
    {
    	p->next = r;
    	pre->next = p;
    }
   
  	}
  	#endif
   
  }
 
	}
	return first;
}
/*
	在链表h中,元素值为k的那个结点的后面,
	增加一个新结点,新结点的数据值为x.
	如果有多个k,则在第一个k后面插入,
	如果没有k,则在末尾插入.
	再把新链表的第一个结点的指针返回。
*/
struct node* insert(struct node *h, int k, int x)
{
	struct node *p = h;
	struct node *pre = NULL;//指向p前面那个结点
	struct node *pnew = malloc(sizeof(*pnew));
	pnew->data = x;
	pnew->next = NULL;
	/*
	step 1: 找插入位置
	*/
	while (p)
	{
  if (p->data == k)
  {
  	break;
  }
  pre = p;
  p = p->next;
	}
	/*
	step 2:插入
	*/
	if (p)
	{
  pnew->next = p->next;
  p->next = pnew;
	}
	else
	{
  pre->next = pnew;
	}
	return h;
}
/*
	在链表h中,元素值为k的那个结点前面
	新增一个结点,其元素值为x.
	如果有多个k值,则在第一个k前面插入,
	如果没有k,则在最后面插入。
	把新链表的第一个结点的指针返回.
*/
struct node* insert_v2(struct node *h, int k, int x)
{
	struct node *p = NULL; //指向第一个k
	struct node *pre = NULL;//指向p前面那个结点
	struct node *pnew = malloc(sizeof(*pnew));
	pnew->data = x;
	pnew->next = NULL;
	if (h == NULL)
	{
  return pnew;
	}
	/*
	step 1: 找插入位置
	*/
	p = h;
	while (p)
	{
  if (p->data == k)
  {
  	//呵呵,终于找到你啦
  	break;
  }
  pre = p;
  p = p->next;
	}
	/*
	step 2: 插入操作
	*/
	if (p) //找到p啦
	{
  if (p == h)//p是第一个结点
  {
  	pnew->next = p;
  	h = pnew;
  }
  else
  {
  	pnew->next = p;
  	pre->next = pnew;
  }
	}
	else
	{
  pre->next = pnew;
	}
	return h;
}
/*
	delete_node:在链表h中,删除
	一个值为x的结点.
	返回删除后的第一个结点
*/
struct node *delete_node(struct node *h, int x)
{
	struct node *first = h; //指向链表的第一个结点
	struct node *px = NULL; //指向要删除的那个结点
	struct node *pre = NULL;//指向px前面那个结点
	/*
	step 1: 找到要删除的那个结点,
	以及它前面那个结点
	*/
	px = first;
	while (px)
	{
  if (px->data == x)
  {
  	break;
  }
  pre = px;//
  px = px->next;
	}
 
	/*
	step 2: 删除  
	*/
	if (px == NULL) //没有您要删除的结点
	{
  return first;
	}
	if (px == first) //要删除的那个结点是第一个结点
	{
  first = first->next;
  px->next = NULL;
  free(px);
  return first;
	}
	else
	{
  pre->next = px->next;
  px->next = NULL;
  free(px);
  return first;
	}
 
}
struct node *delete_all_x(struct node *h, int x)
{
	struct node *first = h; //指向链表的第一个结点
	struct node *px = first; //指向要删除的那个结点
	struct node *pre = NULL;//指向px前面那个结点
	while (1)
	{
  /*
  step 1: 找到要删除的那个结点,
  以及它前面那个结点
  */
  //px = first;
  while (px)
  {
  	if (px->data == x)
  	{
    break;
  	}
  	pre = px;//
  	px = px->next;
  }
  /*
  step 2: 删除
  */
  if (px == NULL)
  {
  	return first;
  }  
  if (px == first) //要删除的那个结点是第一个结点
  {
  	first = first->next;
  	px->next = NULL;
  	free(px);
  	px = first; //下一个开始查找的位置
   
  }
  else
  {
  	pre->next = px->next;
  	px->next = NULL;
  	free(px);
  	px = pre->next; //下一个开始查找的位置
   
  }
 
	}
}
/*
	遍历链表
*/
void print_list(struct node *p)
{
	while (p)
	{
  printf("%d ", p->data);
  p = p->next;
	}
	printf("\n");
}
int main()
{
	struct node *h = create_list();
	print_list(h);
	//int k,x;
	//scanf("%d%d", &k,&x);
	//h = insert(h, k, x);
	//h = insert_v2(h, k, x);
 
	//print_list(h);
	int x;
	scanf("%d", &x);
	h = delete_all_x(h, x);
	print_list(h);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

路过的小熊~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值