单链表

单链表:同一组任意存储单元存储线性表的数据元素(逻辑地址相邻,物理地址不一定相邻)

单链表的优点:插入和删除效率高

单链表的缺点:查找慢、数据密度小,内存碎片严重

pos的位置必须在链表的合理位置,pos< 0 时返回false。对链表进行遍历,遍历完成仍没有找到pos位置。

单链表的结构体:

单链表的结构体由两部分组成,int data数据域和Node* next指针域,指针域保存其下一个节点的地址,通过地址将节点互相链接,头结点数据域为NULL,尾节点指针域为NULL。如图所示:

单链表的插入(头插、尾插、pos位置插)

for(i,q;q->next != NULL && i< pos;q = q->next ,i++)
{
    ;
}
if(i<pos) //已经遍历到尾节点,仍然没有找到pos位置
{
    return false;
}

单链表的删除和插入是类似的,都是通过 next 域的指针来实现的,将删除位置前驱的 next 域的地址该为 删除位置的后继地址。注意:首先要用指针指向删除位置,以便于free(),防止内存泄漏。

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef struct Node
{
	int data;
	struct Node* next;
}Node,*List;

void InitList(List plist)
{
	assert(plist != NULL);

	plist->next =NULL;
}
bool Insert_head(List plist,int val)
{
	Node*p = (Node*)malloc(sizeof(Node));
	p->data = val;
	p->next =plist->next;
	plist->next =p;
	return true;
}
bool Insert_tail(List plist,int val)
{
	Node*p = (Node*)malloc(sizeof(Node));
	Node *q = plist;
	while(q ->next != NULL)
	{	q = q->next ;}
	p->data = val;
	q->next = p;
	p->next = NULL;
	return true;
}

bool Insert_pos(List plist,int pos,int val)
{
	if(pos < 0)
	{
		return false;
	}
	int i=1;
	Node* q=plist;
	for(i,q;q->next != NULL && i< pos;q = q->next ,i++)//找到pos的前一个节点
	{
		;
	}
	if(i<pos)
	{
		return false;
	}
	Node*p =( Node*)malloc(sizeof(Node));
	p->data =val;
	p->next  = q->next ;
	q->next = p;
	return true;
}

Node* Search_pre(List plist,int key)
{
	
	for(Node*q=plist;q->next != NULL;q=q->next )
	{
		if(q->next ->data == key)  //不能为q->next,插入要先找到他的前驱,改变其前驱的next
		{
			return q;
		}
	}
	return NULL;
}
bool Delete(List plist,int key)
{
	Node* p= Search_pre(plist,key);
	Node* q = p->next;
	p->next =p->next ->next ;
	free(q);
	return true;
}

bool Delete_head(List plist,int *rtv)
{
    if(plist->next == NULL)
    {
	return false;
    }
    Node *p = plist->next;
    if(rtv != NULL)
    {
	*rtv = p->data;
    }
    
    plist->next = p->next;
    free(p);

    return true;
}

bool Delete_tail(List plist,int *rtv)
{
    if(plist->next == NULL)
    {
	return false;
    }
    Node *p;//指向倒数第二个点
    for(p=plist;p->next->next!=NULL;p=p->next)
	{
		;
	}
    Node *q = p->next;
    
    if(rtv != NULL)
    {
	*rtv = q->data;
    }
    free(q);
    p->next = NULL;

    return true;
}

bool IsEmpty(List plist)
{
	return plist->next == NULL;
}

void Destroy(List plist)
{
	Node * p =plist->next;
	for(p;p != NULL;p =p ->next)
	{
		free(p);
	}
}
int GetLength(List plist)
{
	int i= 0;
	Node*q=plist->next;
	for(q;q!=NULL;q=q->next)
	{
		i++;
	}
	return i;
}
void Show(List plist)
{
  for(Node*p=plist->next ;p !=NULL;p=p->next )
  {
	  printf("%d ",p->data);
  }
  printf("\n");
}

int main()
{
	Node head;
	InitList(&head);
	printf("头插 3 2 1\n");
	Insert_head(&head,3);
	Show(&head);
	Insert_head(&head,2);
	Show(&head);
	Insert_head(&head,1);
	Show(&head);

	printf("尾插 4 5 6 \n");
	Insert_tail(&head,4);
	Show(&head);
	Insert_tail(&head,5);
	Show(&head);
	Insert_tail(&head,6);
	Show(&head);
	printf("在4号位置插入 100 \n");
	Insert_pos(&head,4,100);
	
	Show(&head);
	printf("删除数据 100\n");
	Delete(&head,100);
	Show(&head);
	printf("删除第一个数据\n");
	Delete_head(&head,NULL);
	Show(&head);
	printf("删除最后一个数据\n");
	Delete_tail(&head,NULL);
	Show(&head);
	printf("链表的长度为:");
	int index = GetLength(&head);
	printf("%d\n ",index);
	Destroy(&head);
	return 0;
}

执行结果:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值