数据结构——单链表学习

单链表

1. 单链表的定义

单向不带头不循环链表

typedef int SLTDateType;   //数据类型别名定义

typedef struct SListNode
{
  SLTDateType data;        //data用来储存数据
  struct SListNode* next;  //定义next指针用来链接
}SLTNode;

2. 创建节点

SLTNode* BuyListNode(SLTDateType x)
{
	SLTNode* newnode =(SLTNode*)malloc(sizeof(SLTNode));  
	if(newnode == NULL)
	{
	  printf("malloc fall\n");
	  exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	return newnode;
};

3. 打印链表

void SListPrint(SLTNode* phead){
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d",cur->data);
		cur = cur->next;
	}
	printf("\n");
};

4. 尾插

void SListPushBack (SLTNode** pphead,SLTDateType x){   //传二级指针,通过改变形参来改变实参
    assert(*pphead != NULL);
	SLTNode* newnode = BuyListNode(x);
    if(*pphead == NULL)
	{
	  *pphead = newnode;             //如果头指针为空,直接让头指针指向新结点
	}
	else
	{
	  SLTNode* tail = *pphead;
	  while (tail->next != NULL)    //找尾 
	  {
		  tail = tail->next;
	  }            
	  tail->next = newnode;        //把尾结点接上新结点
	}
};

5. 头插

void SListPushFront (SLTNode** pphead,SLTDateType x){
	assert(*pphead != NULL);
	SLTNode* newnode = BuyListNode(x);
	newnode->next = *pphead;  //新结点的next指向之前的头
	*pphead = newnode;        //再把头指针前移
};

6. 尾删

void SListPopBack(SLTNode** pphead){
	assert(*pphead != NULL);     //判断是否有数据可删
	if((*pphead)->next == NULL)  //如果链表只有一个结点
	{
	   free(*pphead);
	   *pphead = NULL;
	}
	else
	{
	   SLTNode* prev = NULL;     //定义一个新的指针,来保存移动之前的地址
	   SLTNode* tail = *pphead;  
	   while (tail->next != NULL)//找尾,且保存尾之前的结点位置到prev
	   {
	      prev = tail;
		  tail = tail->next;
	   }	
	   free(tail);              
	   tail = NULL;
	   prev->next = NULL;        //删除尾节点,并且给新的尾节点next指针赋上空
	}
};

7. 头删

void SListPopFront(SLTNode** pphead)
{          
	assert(*pphead != NULL);     
    SLTNode* prev = (*pphead)->next;     //定义一个指针指向头节点后面那个节点
	free(*pphead);              //删除头节点
	*pphead = prev;             //将头指针指向新的头节点
};

8. 查找

SLTNode* SListFind(SLTNode* phead,SLTDateType x)
{
   assert(phead != NULL);
   SLTNode* cur = phead;
   while (cur)
   {
     if(cur->data == x)
	 {
       return cur;
	 }
	 else
	 {
	   cur = cur->next;
	 }
   }
   return NULL;
};

9. 在pos位置之前去插入一个节点

void SListInsert(SLTNode** pphead,SLTNode* pos,SLTDateType x)
{
	assert(*pphead != NULL);
	assert(pos != NULL);
	SLTNode* newnode =BuyListNode(x);
	if (*pphead == pos)                 //如果pos位置为头节点位置
	{
		newnode->next = *pphead;        
	    *pphead = newnode;
	}
	else
	{ 
	    SLTNode* posPrev = *pphead;    
		while (posPrev->next != pos)   //找到pos位置的前一个节点位置,储存到posPrev里面
		{
			posPrev = posPrev->next;
		}
		posPrev->next = newnode;      
		newnode->next = pos;
	}
}

10. 在pos位置之后去插入一个节点

void SListInsertAfter(SLTNode* pos,SLTDateType x)
{
	assert(pos != NULL); 
	SLTNode* newnode = BuyListNode(x);
	newnode->next = pos->next;       //必须先让新节点的next先指向后面结点
	pos->next = newnode;             //再让pos的next指向新结点
};

11. 删除pos位置节点

void SListErase(SLTNode** pphead,SLTNode* pos)
{   
	assert(*pphead != NULL);
	assert(pos != NULL);
	if(*pphead == pos)               //如果pos位置是头节点
	{
	  *pphead = pos->next;
	  free(pos);
	}
	else
	{
	  SLTNode *prev = *pphead;       //找到pos位置的前一个节点位置,储存到prev里面
	  while (prev->next != pos)
	  {
		  prev = prev->next;
	  }
	  prev->next = pos->next;        //将pos位置前一个节点和pos位置后一个节点链接
	  free(pos);
	}
};

12. 删除pos位置的后面一个节点

void SListEraseAfter(SLTNode* pos)
{   
	assert(pos !=NULL);
	assert(pos->next != NULL);       //如果pos为尾节点
	SLTNode* prev = pos->next;
	pos->next = prev->next;
	free(prev);
};

13. 链表的销毁

void SListDestory(SLTNode** pphead)
{
	assert(*pphead != NULL);
	SLTNode* cur = *pphead;
	while (cur)                     //依次释放节点
	{
		SLTNode* prev = cur->next;
	    free(cur);
		cur = prev;
	}
	*pphead = NULL;                 //头指针赋空
};

14. 单链表的优缺点

1. 优点

(1)存储空间动态分配,只要有内存空间,数据就不会溢出。
(2)便于实现插入与删除操作。

2. 缺点

(1)存储空间不一定连续,内容分散,有时会导致调试不便。
(2)每一个结点(除头结点)都有数据域与指针域,增大存储空间的开销。
(3)单链表查找结点时,需要从头开始查找,增加查找时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值