数据结构之链表

对于数据结构问题,首先来谈谈关于链表的问题,关于链表的操作无非就是生成,遍历,增加,删除,其他的操作都是建立在这4种操作上面的。理解链表关键是关于指针节点的操作,

1.定义链表数据结构与动态分配内存

定义链表节点,拿数字作为值为例子

typedef struct Node
{
    int data;
    Node* next;
}Node
Node* p=(Node*)malloc(sizeof(Node));

2.生成一个链表

生成链表其实就是定义一个新节点不断往前一个节点插入的过程,这里需要定义3个指向链表节点指针就够了,一个保存头节点作为函数的返回值;一个保存上一节点,用来进行连接链表;一个定义新的节点,用来生成新的节点。

代码如下:

Node* Create() //定义了一个创建链表的函数,返回链表的头指针
{
	Node* p;     //这个指针用来定义新节点,需要不断新生成
	Node* pHead;  //这个指针用来保存头结点,其实就使用一次
	Node* pTemp;     //临时指针,这个指针用来保存p1节点的上一节点,用来连接链表
	p=(Node*)malloc(sizeof(Node));
	if(p==NULL)
	{
		printf("初始化错误");
		return NULL;
	}
	memset(p1,0,sizeof(p));
	scanf("%d",&p->data);
	p->next=NULL;
	//移动指针
	pHead=p;               //pHead指针就用了这一次,做为返回值就行
	//用来保存头节点
	pTemp=p;
	while(p->data!=0) //输入0链表生成完成
	{
		p=(Node*)malloc(sizeof(Node)); //不断开辟新的节点
		memset(p,0,sizeof(p));
		scanf("%d",&p->data);
		p->next=NULL;
		pTemp->next=p //核心语句,连接链表,这里的pTemp其实是是新生成p节点的上一节点,链表生成的关键
		pTemp=p;                          //移动指针,为下一次连接做准备
	}
	return pHead;
}

3.遍历链表,遍历链表其实很简单,就是一个指针不断下移的过程。

p=p->next;

当p为空是就退出,传入链表的头指针.

void Traversal(Node *p)
{
	if(p==NULL)
	{
	   printf("链表不存在");
	   return;
	}
	while(p!=NULL)
	{
	   printf("%d",p->data);
	   p=p->next;//核心代码,遍历链表
	}
	printf("\n");
}

3.插入某一节点,插入节点就3部分,定义新节点,查找插入位置,重新;连接

void Insert(Node** pHead,int Pos,int num)
{ 
	int Size=0;
	Node* pTemp;
	pTemp=*pHead;
	if(*pHead==NULL)
	{
		printf("链表不存在");
		return;
	}
	//第一步定义新的需要插入的节点
	Node* p;
	p=(Node*)malloc(sizeof(Node));
	p->data=num;
 
	//第二步查找要插入的位置
	while(pTemp->next!=NULL)
	{
		++Size;
		if(Size==Pos)
		{
			//找到了指定的插入位置
			//第三步 重新连接 
			p->next=pTemp->next;
			pTemp->next=p;
		        //上面2部插入的核心代码,注意:顺序不能弄反了,一定要先连后节点,再连前节点,如果反了的话,像这样
		        // px->next=p;
			// p->next=px->next;	
			// 其实就是
			// p->next=p;产生无限循环,好比狗追尾巴一样,一直在原地打转
			break;
		}
		pTemp=pTemp->next;
	}
 
	if(Size<Pos)
	{
		printf("插入的位置不正确");
		return;
	}
}

4.删除某一节点

删除节点分2部分,查找与断链重连,在这里我把删除头节点单独拿出来写了,注意这里删除的顺序我还是从0开始,并不是从1开始的。

Node* DeleteNode(Node** pHead,int Pos)
{
	int Size=0;
	Node* pTemp;
	pTemp=*pHead;
	if(*pHead==NULL)
	{
		printf("链表不存在");
		return NULL;
	}
 
	while(pTemp!=NULL)
	{
		if(Pos==0)
		{
			*pHead=(*pHead)->next;
			free(pTemp);		
			return *pHead;
		}
		else
		{
			++Size;
			if(Size==Pos)
			{
				Node* pDelete=pTemp->next;
				pTemp->next=pDelete->next; //核心代码,定义一个指向需要删除的节点的指针,把删除节点前一节点的指针连接删除节点的后继节点即可,
				free(pDelete);             //删除节点
				return *pHead;
				break;
			}
			
			pTemp=pTemp->next;
		}
	}
 
	if(Size<Pos)
	{
		printf("删除的位置不正确");
		return *pHead;
	}
}

 总结:链表的操作,定义临时节点与新节点,新节点用来分配内存,创建链表,临时节点用来遍历链表,链表的核心语句其实就只有下面这几行代码

Node* p;
p=(Node*)malloc(sizeof(Node));
p=p->next;
p->next=pTemp->next;
pTemp->next=p;
Node* pDelete=pTemp->next;
pTemp->next=pDelete->next

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值