C语言实现链表的创建、 插入 和删除 反向打印链表

1,动态链表的创建

I 在每次生成新节点的时候使用库函数 malloc 动态分配存储空间

II 创建过程需要两个指针p1和p2:

         刚开始p1和p2指向头结点,

         然后p1指向新生成的结点。

         p2是当前节点,p2的下一个节点指向新生成的结点p1.

         p2后移到当前新生成的结点p1

         创建新节点p1

III 使链表尾部指向空代表结束

参考 C语言程序设计(第五版)谭浩强著 P312~P314

代码实现:

//链表的结点的组成
struct LinkedList{
	int val;
	struct LinkedList *next;
};
//创建链表,并返回链表头结点的指针
struct LinkedList *createLinkedList(int vals[],int n)
{
	if(sizeof(vals)<sizeof(int) || n < 0) //对输入的合法性检查
		return NULL;
	struct LinkedList *head,*p1,*p2;	//head 是链表的头结点,在第一个结点被创建时赋值
	int i = 0;
	p1 = p2 = (struct LinkedList *)malloc(sizeof(struct LinkedList));//先使p1和p2指向第一个结点
	p1->val = vals[i];
	head = NULL;
	
	while(i<n)
	{
		if(i == 0)
			head = p1;
		else
			p2->next = p1;	//如果新增一个非头结点,则插入到表尾
		p2 = p1;	//p2后移,指向新增的结点
		i++;
		if(i != n)	//只有当数组中的元素还没有被添加到结点,生成一个新节点
		{
			p1 = (struct LinkedList *)malloc(sizeof(struct LinkedList));
			p1->val = vals[i];
		}
		
	}
	p2->next = NULL;	//使链表的尾部指针为空
	return head;	//创建完链表后返回该链表的头指针
}

2,在链表的指定位置插入结点,返回插入后新链表的头结点

struct LinkedList *insertListAfter(struct LinkedList *L,int index,int num)
{
	//输入的合法性检查
	if(L == NULL || index < 0)
		return NULL;
	struct LinkedList *p,*s; //s 指向要插入的结点
	int i = 0;
	p = L;
	while(p!=NULL && i<index-1)//找到结点要插入的位置
	{
		p = p->next;
		i++;
	}
	s = (struct LinkedList *)malloc(sizeof(struct LinkedList));
	s->val = num;
	if(index == 0)
	{
		s->next = p; //在表头插入结点
		return s;
	}
	s->next = p->next;//把待插入结点后面部分连接起来
	p->next = s;//
	return L;//返回链表的头结点指针
}

3,删除链表的指定结点

struct LinkedList *deleteList(struct LinkedList *L,int index,int len)
{
	//输入合法性检查
	if(L == NULL ||index<0 || index >len-1)
		return NULL;
	struct LinkedList *p,*q;
	int i = 0;
	p = L;
	while(p && i<index - 1)//找到要删除节点的前一个节点的位置
	{
		p = p->next;
		i++;
	}
	if(index == 0) 
	{
		q = p->next;
		free(p);
		return q;
	}
		
	q = p->next;
	p->next = p->next->next;
	free(q);//释放结点
	return L;
}

4,链表的反向打印有三种思路

        a,先把先把链表翻转,然后从头开始打印

        b,遍历链表,没遍历一个节点就存入栈中。遍历完后再从栈顶弹出节点值,这种方法需要开辟一个栈,需要额外的存储空 间。

        c,利用递归,此方法不适用于较长的链表

面试的时候,采用递归法即可

void printLisrReversingly(struct LinkedList *head)
{
	if(head != NULL) //输入合法性检查,防止出现输入空指针
	{
		if(head->next != NULL)
		{
			printLisrReversingly(head->next);
			
		}
		printf("node:%d\t",head->val);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值