C语言单链表基本操作

  单链表的基本操作包括初始化、取值、查找、插入、删除、单链表的创建

初始化之前,先进行宏定义和类型定义:

#define OK 1
 #define ERROR 0
 
 typedef int Status;
 typedef int ElemType;
 
 typedef struct LNode{
        ElemType data;
        LNode *next;
 }LNode,*LinkList;


初始化:

StatusInitList(LinkList L)
{
        L = (LNode *)malloc(sizeof(LNode));
        if (!L)
                  return ERROR;
        L->next = NULL;
        return OK;
}


思想:初始化的目的是为了给链表L的头结点分配空间,if()判断分配是否成功,并将链表头结点指针域设置为NULL

取值:

Status GetElem(LinkList L, int i,ElemType *e)
{
        int j = 1;
        LinkList p;
        p = L->next;
        while (p&&j < i)
        {
                  p = p->next;
                  j++;
        }
        if (!p || j>i)
                  return ERROR;
        *e = p->data;
        return OK;
}


思想:声明指针p,并使p指向首元节点。判断p指向的结点是否存在,并且是否已经指向所要取值的结点,若p指向所要取值的结点将该节点的data数据赋值给*e,否则p顺着next指向下个结点。

插入:

Status ListInsert(LinkList L, int i, ElemType e)
{
        LinkList p,s;
        int j=0;
        p = L;
        while (p&&(j < i-1))
        {
                  p = p->next;
                  j++;
        }
        if (!p || j>i - 1)
                  return ERROR;
        s = (LNode *)malloc(sizeof(LNode));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return OK;
}


思想:找到所要插入结点的位置p,生成一个新的结点*s,将s的指针域指向p的下一个结点,将p的指针域指向s

删除:

Status ListDelete(LinkList L, int i)
{
        LinkList p,q;
        int j = 0;
        p = L;
        while (p && (j < i-1))
        {
                  p = p->next;
                  j++;
        }
        if (!p || (j>i-1))
                  return ERROR;
        q = p->next;
        p->next = q->next;
        free(q);
        return OK;
}


思想:找到要删除结点,并让p指向向该节点,找到后把q指向p的下一个结点,将p的指针域指向q的下一个结点,释放q结点。

加入main()测试:

intmain(void)
{
        int n, i;
        LNode L;
        ElemType e, *p;
        p = &e;
        printf("1.初始化\n2.取值\n3.查找\n4.插入\n5.删除\n6.退出\n");
        while (1)
        {
                  printf("请选择:");
                  scanf("%d", &n);
                  switch (n)
                  {
                  case 1:
                           if (InitList(&L) == OK)
                                    printf("初始化成功!\n");
                           else
                                    printf("初始化失败!\n");
                           break;
                  case 2:
                           printf("请输入你要取值的序号:");
                           scanf("%d", &i);
                           if (GetElem(&L, i, p) == OK)
                                    printf("该值为:%d\n",*p);
                           else
                                    printf("取值失败!\n");
                           break;
                  case 3:
                           printf("输入你要查找的值:");
                           scanf("%d", &e);
                           printf("你要查找的值的地址为:%d\n",LocateElem(&L, e));
                           break;
                  case 4:
                           printf("请输入插入的位置和数据:");
                           scanf("%d %d", &i, &e);
                           if (ListInsert(&L, i, e) == OK)
                                   printf("插入成功!\n");
                           else
                                    printf("插入失败!\n");
                           break;
                  case 5:
                           printf("请输入要删除的结点的序号:");
                           scanf("%d", &i);
                           if (ListDelete(&L, i) == OK)
                                    printf("删除成功!\n");
                           else
                                    printf("删除失败!\n");
                           break;
                  case 6:
                           exit(0);
                  }
        }
        return 0;
}


现在就可以对链表进行操作了。

C语言单链表基本操作

关于单链表创建,存在两种方法:前插法和后插法。

前插法:

void CreateList_H(LinkList L, int n)
{
        LinkList p;
        int i;
        for (i = 0; i < n; i++)
        {
                  p = (LNode *)malloc(sizeof(LNode));
                  scanf("%d", &p->data);
                  p->next = L->next;
                  L->next = p;
        }
}


思想:生成一个新结点*p并将元素赋值到*p指向的数据域。将新结点插到头结点之后。

后插法:

void CreateList_R(LinkList L, int n)
{
        LinkList p,r;
        int i;
        L->next = NULL;
        r = L;
        for (i = 0; i < n; i++)
        {
                  p = (LNode *)malloc(sizeof(LNode));
                  scanf("%d", &p->data);
                  p->next = NULL;
                  r->next = p;
                  r = p;
        }
}


思想:让r指针指向链表最后一个结点,每一次插入都分配内存,让p指向该区域。让p指针域设置为NULL,将r指针域指向p,最后将指针r指向p

测试用main():

int main(void)
{
    LNode L;
    ElemType e, *p;
    int n, i;
    p = &e;
    printf("输入你要创建的长度:");
    scanf("%d", &n);
    CreateList_R(&L,n);
    while (1)
    {
        printf("1.取值\n2.退出\n");
        scanf("%d", &n);
        if (n == 1)
        {
           printf("输入你要取值的序号:");
           scanf("%d", &i);
           if (GetElem(&L, i,p) == OK)
           {
               printf("该值为:%d\n",e);
           }
           else
             printf("查找失败!\n");
         }
         else
           exit(0);
      }
      return 0;
 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值