C语言单链表基础

 

前言

一直以来对链表都理解的不深,没有个系统的总结学习。今天趁有空,总结一下,方便日后查阅。

一、链表

链表是C语言中的一种数据结构,链表由一系列结点(链表中每一个元素称为结点)组成,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。由此可见,链表不像malloc的一块内存一样是连续顺序存储的,每个节点靠一个指针连接,指针指向的就是下个节点的地址。这就和数组有不同了,数组是在内存中是连续存储的,每个位置下标存入的是固定的值,所以查找很方便,但是如果要求快速插入和删除,数组就显得很局促了。但是链表就可以很快速的插入和删除,因为链表的数据是靠地址链接,我们只需要改变地址指向就可以了。

二、使用链表及链表的基本操作

链表定义

typedef struct Node

{

         int data;

         struct  Node *next;

}NODE,pNODE;

可以看出,一个链表节点是由一个数据域和一个指针域组成。指针域的类型是一个完整的链表结构。注意此处用法,在链表内部定义链表节点的时候,要使用Node,而不是NODE,原因是typedef的用法。在typedef还没执行完的时候,NODE是未定义的,所以会出现未定义错误。

链表的基本操作为创建、查找、增加和删除。

下面贴个代码。

#include <stdio.h>
#include <stdlib.h> 
typedef struct Node
{
   int data;
   struct Node *pNext;
}NODE,*pNODE;


pNODE CreateList(void)
{
	int i, length, data;
	pNODE p_new = NULL, pTail = NULL;
	
	pNODE pHead = (pNODE)malloc(sizeof(NODE));//见注1

	if (NULL == pHead)
	{
		printf("内存分配失败!\n");
		exit(EXIT_FAILURE);
	}
 
	pHead->data = 0;
	pHead->pNext = NULL;
	pTail = pHead;//见注2
 
	printf("请输入要创建链表的长度:\n");
	scanf("%d", &length);
 
	for (i=1; i<length+1; i++)
	{
		p_new = (pNODE)malloc(sizeof(NODE));
      
		if (NULL == p_new)
		{
			printf("内存分配失败!\n");
			exit(EXIT_FAILURE);
		}
 
		printf("请输入第%d个节点的值:\n", i);
		scanf("%d", &data);
 
		p_new->data = data;
		p_new->pNext = NULL;
		pTail->pNext = p_new;
		pTail = p_new;
	}
	return pHead;
}


void PrintList(pNODE pHead)
{
	pNODE pt = pHead->pNext;
 
	printf("打印链表:\n");
	while (pt != NULL)
	{
		printf("%d ", pt->data);
		pt = pt->pNext;
	}
	putchar('\n');
}


int IsEmpty(pNODE pHead)
{
	if (pHead->pNext == NULL)
		return 1;
	else
		return 0;
}
int GetListLength(pNODE pHead)
{
   int length = 0;
   pNODE p = pHead->pNext;
   while(p != NULL)
   {
      length++;
      p = p->pNext; 
   }
   return length;
}
void insertMylist(pNODE pHead,int addr,int data)
{
   pNODE pt = (pNODE)malloc(sizeof(NODE));
   pt->data = data;
   while(1)
   {
      if(pHead->data == addr)
      {
         pt->pNext = pHead->pNext;
         pHead->pNext = pt;
         break;
      }
      pHead=pHead->pNext;
   }
}
void deleteMylist(pNODE pHead,int addr)
{
	pNODE pt;
	while(1)
	{
		
		if(addr == pHead->data)
		{
			pHead = pHead->pNext;
			break;
		}
		pt = pHead;//见注3
		pHead = pHead->pNext;
		
	}
	free(pt->pNext);//见注4
    pt->pNext = NULL;
	pt->pNext = pHead;


}
int main ()
{
   pNODE Mylist = CreateList();
   PrintList(Mylist);
   printf("length is %d \n",GetListLength(Mylist));
   insertMylist(Mylist,3,100);
   PrintList(Mylist);
   printf("delete %d \n",3);
   deleteMylist(Mylist,3);
   PrintList(Mylist);
   return(0);
}










 

几点解释,大佬绕行。

注1:创建头节点,头结点是第0个节点,后面的节点从1开始计数。

注2:头结点地址给尾结点,创建链表操作都在尾结点进行插入,保证头结点不变。

注3:记录查询到的上次节点位置。

注4:删除节点要进行free操作,否则会有内存泄漏。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值