单链表-不带头结点(创建,插入)

为什么要使用链表,因为链表可以连接数据类型不一样的数据,而一个数组中只能使用一种数据类型。
以学生为例:
一个学生有学号,姓名,年龄,性别,等,先拿这四个用着。开始下面的内容:
1、创建链表
首先我们要创建单链表中的每一个结点模型,就是创建一个结点模型,后面要用就往里面填数据就行。链表的结点有两个域,一个是值域,一个是指针域,指针域就是指向下一个链表的位置。所以我们要使用结构体来定义这两个域中的变量。看代码:在这里插入图片描述
然后需要头指针,这个头指针的类型也必须是这个结构体指针类型,指针也是有类型的,所以我们还需要定义结构体指针类型,看代码:
在这里插入图片描述
这里需要注意的是第一个定义的是结构体变量,第二个定义的是结构体指针类型就是要这样看:在这里插入图片描述
这里是为了方便后面少些点,所以就在这里定义,用Link代表Node *,后面再用Link来定义该类型的指针变量。
到这里我们就需要创建链表了,起始创建的是一个空链表:
就是定义一个头指针(Link head = NULL),这个头指针指向空,说明是一个空链表,必须给指针变量有明确的指向,不能没有指向。(防止出现野指针)。创建链表实参是地址(指针),形参要用二级指针来接,看代码
在这里插入图片描述
在这里插入图片描述
我们链表创建完成,然后就是创建结点了,这个结点就是上面定义的结构体,他是个模型,所以要定义一个结构体指针来指向将要分配给它内存的首地址,现在我们要给它分配内存和赋值了,这里分配内存时用malloc动态分配的,后面需要将这个内存回收。看代码:在这里插入图片描述

在这里插入图片描述
这里函数的参数时二级指针,二级指针是对数据的地址进行操作,一级指针是对数据本身进行操作。
结点创建完成并赋值,这里为了方便就给num进行赋值,其余先不管:
在这里插入图片描述
以上就是链表的创建,现在有了头指针,有了第一个要插入的结点,下面就要进行插入操作。
2、插入
编写插入函数在主函数里调用
这里插入有三种方法,头插法尾插法中间插法
首先看头插法
在这里插入图片描述在这里插入图片描述
注意头插法需要不断的修改头指针所指向的地址,所以函数的形参要用二级指针。然后就是指针指向的变动了,上面一共形成十个同学的数据,所以有十个结点。
这个就是头插法。

尾插法
尾插法就是在链表的最后一个结点后插上新的结点。
在这里插入图片描述
中间插法
中间插入法需要定义两个结构体类型的指针变量p和q,指向头指针指向的地址。后面就是根据要插入结点位置,来确定q和p的指向,然后进行插入
在这里插入图片描述删除和查找后续加上。

以下是链表的创建和插入源代码:


#include <stdio.h>
#include <stdlib.h>
/*
 * 链表的中间插法
 *
 *   创建单链表步骤:
 *1、单链表有指针域和值域,先创建值域和指针域
 *2、定义一个结构体类型和结构体的指针类型
 *3、有了指针创建链表
 *4、链表没有结点在创建结点
 *5、插入结点
 *6、释放空间
 *
 */


//创建链表结点,结构体包含值域和指针域
struct node
{
    int num;
    char name;

   struct node *next;  //指针域
};


typedef struct node Node; //定义结构体变量名
typedef Node * Link;      //定义结构体指针类型

//创建链表
void create_link(Link *head)
{
    *head = NULL;  //空链表
}

//创建结点
void create_node(Link *new_node)
{
    *new_node = (Link)malloc(sizeof(Node));
}

//尾插法函数
void insert_node_tail(Link *head, Link new_node)
{  
    Link p = NULL;
    p = *head;

    if(NULL == p)
    {
        *head = new_node;
        new_node->next = NULL;
    }
    else
    {
        while( p->next != NULL)
        {
            p = p->next;
        }

        p->next = new_node;
        new_node->next = NULL;
    }
    
}

//头插法函数
void insert_node_head(Link *head, Link new_node)
{
    new_node->next = *head;
    *head = new_node;
}

//中间插入法函数
void insert_node_mid(Link new_node, Link *head, int loc)
{
    Link p = NULL;
    Link q = NULL;
    
    p = q =  *head;

    while( p != NULL && p->num != loc)
    {
        q = p;
        p = p->next;
    }

    if(p  == *head)
    {
        new_node->next = *head;
        *head = new_node;
    }
    else
    {
        q->next = new_node;
        new_node->next = p;
        
    }

    
}

//列出链表
void display_link(Link head)
{
    Link p = NULL;
    p = head;

    while( p != NULL)
    {
        printf("%d\n",p->num);

        p = p->next;
    }
}


//释放结点空间
void release_link(Link *head)
{
    Link p = NULL;
    p = *head;
    
    while(*head != NULL)
    {
        *head = (*head)->next;
        free(p);
        p = *head;
    }

    if(*head == NULL)
    {
        printf("link is empty!");
    }

    printf("\n");
}


int main(int argc, char **argv)
{
    //定义一个头指针
    Link head = NULL;
    Link new_node = NULL;
    int i;
    int loc;

    //创建链表
    create_link(&head);
    
    printf("please input loc:\n");
    scanf("%d",&loc);

    printf("please input num:\n");
      
    for(i = 0; i < 10; i++)
    {
        create_node(&new_node);
        new_node->num = i + 1;

        insert_node_tail(&head, new_node);
    }

   /* for(i = 0; i < 10; i++)
    {
        create_node(&new_node);
        new_node->num = i + 1;

        insert_node_head(&head, new_node);
    }
    */

    //创建新结点
    create_node(&new_node);
       
    scanf("%d",&new_node->num);
    //插入结点
    insert_node_mid(new_node, &head, loc);

    //列出链表
    display_link(head);

    //释放空间
    release_link(&head);

    return 0;
}

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
头插法是一种创建链表的方法,通过在链表的头部插入新的节点来创建链表。具体的步骤如下: 1. 创建一个头结点,将其next指针指向NULL,这个头结点将作为链表的表尾节点。 2. 输入要插入链表的数据,将其作为新节点的数据域。 3. 创建一个新节点,并将新节点的next指针指向头结点的next指针指向的节点。 4. 将头结点的next指针指向新节点,使新节点成为链表的新的头节点。 5. 重复步骤2到步骤4,直到结束输入。 6. 遍历链表,从头结点的next指针开始,依次输出各节点的数据域。 下面是一个使用头插法创建链表并输出的示例代码: ```c #include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; } Node; void printList(Node *head); Node *createList(); int main() { Node *head = createList(); printList(head); return 0; } void printList(Node *head) { Node *p = head->next; while(p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } Node *createList() { Node *head = (Node *)malloc(sizeof(Node)); head->next = NULL; int num; while(scanf("%d", &num) && num != 0) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = num; newNode->next = head->next; head->next = newNode; } return head; } ``` 你可以按照这个示例代码的步骤,使用头插法创建链表并输出。在输入数据时,以0作为结束标志。然后调用printList函数遍历链表并输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值