三种链表的定义和基本操作

这篇博客详细介绍了单链表的定义、初始化、判空操作,包括不带头节点和带头节点两种情况。接着讨论了查找、插入和删除等基本操作,如按位查找、按值查找、后插、前插、按位插入和删除等。同时提到了建立单链表的头插法和尾插法。

单链表

不可随机存取

定义及初始化 判空

注意:
LNode 是强调返回的是一个结点
LinkList 是强调返回的是一个链表

不带头节点的单链表

头指针L指向的是实际的元素结点,即指向实际的值

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;
//初始化
bool InitList(LinkList &L)	//注意这里L前面要加&,因为值需要带回
{
    L = NULL;
    return true;
}
//判空
bool Empty(LinkList L)	//此处L前不用&
{
    return (L==NULL);
}

带头结点的单链表

初始化

  1. 分配一个结点,类型是LNode,称为头结点,头指针指向头结点
  2. 判断分配是否成功
  3. 头结点后无结点
//带头结点初始化
bool InitList(LinkList &L)
{
    L = (LNode *)malloc(sizeof(LNode));     //分配一个头结点
    if(L==NULL) return false;   //内存不足,分配失败
    L->next = NULL;
    return ture;
}
//判空
bool Empty(LinkList L)	
{
    return (L->next ==NULL);
}

查找

按位查找GetElem(L,i)

找到第i个结点

  1. 判断i是否合法
  2. 定义一个指针p(指向扫描到的结点
  3. 定义 j 为指向结点的位置
  4. 让p先指向头结点
  5. 用while循环,实现p向后移直到找到i位置结点
//带头结点
bool GetElem(LinkList L, int i)
{
    if(i<1) return false;
    LNode *p;   //指针p指向当前扫描到的结点
    int j=0;    //当前p指向结点是第几个
    p = L;  //L指向头结点,即第0个结点(不存数据)
    while([p!=NULL&&j<i])
    {
        p = p->next;
        j++;
    }
    return p;
}

按值查找LocateElem(L,e)

LNode * LocateElem(LinkList L, int e)
{
	LNode *p = L->next;		//从第一个结点开始查
	while(p!=NULL&&p->data!=e)
		p = p->next;
	return p;
}

插入

后插操作InsertNextNode(p,e)

在P结点后插入值为e的结点

  1. 判断p结点存不存在
  2. 申请一个结点s
  3. 先把e的值给s
  4. s指向p的下一结点
  5. p指向s
bool InsertNextNode (LNode *p, int e)
{
    if(p==NULL)
        return false; //p结点不存在,因为找到p结点要调用GeteLem函数,*p可能为NULL
    LNode * s = (LNode *)malloc(sizeof(LNode));
    if(s==NULL) return false;   //内存分配失败
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

前插操作InsertPriorNode(p,s)

在p结点前插入结点s

  1. s后插在p后
  2. 将s和p的数据值交换
bool InsertPriorNode(LNode *p,LNode *s)
{
    if(P==NULL||s==NULL) return false;
    s->next = p->next;
    p->next = s;
    int temp = p->data;
    p->data = s->data;
    s->data = temp;
    return true;
}

按位插入 ListInsert(L,i,e)

带头结点

在i位置插入值为e的结点

LNode *p = GetElem(L,i-1);	//找到第i-1个结点
return InsertNextNode(p,e)	//后插
不带头结点

在第一个位置要特殊处理

if(i==1)
{
	LNode *s = (LNode *)malloc(sizeof(LNode));
	s->data = e;
	s->next = L;
	L = s;
	return true;
}

删除

按位删除ListDelete(L,i,e)

删除第i个位置的元素,并把值用e带回

  1. 找到第i-1个结点
  2. 判断p存不存在(即i合不合法,i位置结点存不存在)
  3. 定义一个指针q指向被删结点
  4. 把被删结点的值赋给e
  5. 把p的后驱指向q的后驱
  6. 释放q
bool LinkDelet(LinkList &L, int i, int e)
{
    LNode *p = GetElem(L,i-1);
    if(p==NULL) return false;
    if(p->next==NULL) return false;
    LNode *q = p->next;
    e = q->data;
    p->next = q->next;
    free(p);
    return true;
}

删除指定结点DeleteNode§

删除指定结点p

  1. 定义指针q指向p的后驱结点
  2. 把q的数据值赋给p
  3. p的后驱指向q的后驱
  4. 释放q
bool DeleteNode(LNode *p)
{
	if(p==NULL) return flase;
	LNode * q = p->next;
	p->data = q->data;
	p->next = q->next;
	free(p);
	return true;
}

注意:当p是最后结点时,不能用上述方法,只能从表头开始找p的前一个结点

建立

头插法

链表的逆置

LinkList List_HeadInsert(LinkList &L)
{
    LNode *p;    //p为要插入的元素
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;
    for(int i = 0;i<n;i++)
    {
        p = (LNode *)malloc (sizeof(LNode));
        scanf("%d",&p->data);
        p->next = L->next;
        L->next = p;
    }
    return L;
}

尾插法

顺序存储,注意要有个结点始终指向尾结点

LinkList List_TailInsert(LinkList &L)
{
    LNode *p,*r = L;    //p为要插入的元素.r始终指向表尾元素
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;
    for(int i = 0;i<n;i++)
    {
        p = (LNode *)malloc (sizeof(LNode));
        scanf("%d",&p->data);
        p->next = r->next;
        r->next = p;
        r = p;
    }
    return L;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值