单链表的插入和删除

   常见的数据结构只有两种:

   1、数组

   2、链表 

   数组中的元素是连续存储的,而链表的元素则可以不连续,只需要有指针指向下一个元素即可。因此链表适合存储插入删除比较频繁的一组数据。另外链表的存储空间是动态的,不必预先分配指定的空间大小。。下面介绍链表的几种常见操作。

   首先先定义一个链表

   

  struct linklist {

    int data;

    struct linklist *next;

  };


  typedef linklist *linklistp;


 然后定义两个函数:

  

/**

 头结点插入

 */

linklistp insert_head(linklistp head,linklistp newnode){

   

    newnode->next = head;

    head = newnode;

    

    return head;

    

}

/**

 尾结点插入

 */

linklistp insert_tail(linklistp head,linklistp newnode){

    

    if(head == NULL){

        head = newnode;

        return head;

    }

    

    linklistp temp = head;

    while (1) {

        if(temp->next == NULL){

            

            temp->next = newnode;

            break;

            

        }

        temp = temp->next;

    }

    return head;

}

之后我们利用尾节点插入的函数来创建一个链表

    linklistp head = NULL;

    for(int i = 0;i < 10; i ++){

        linklistp newNode = (linklistp)malloc(sizeof(linklist));

        newNode->data = i;

        newNode->next = NULL;

        head = insert_tail(head,newNode);

    }


这样就创建了一个包含十个元素的链表。

然后再定义一个函数,求链表长度

/**

 获取链表长度

 */

int getLength(linklistp head){

    

    if(head == NULL){

        return 0;

    }

    

    int count = 1;

    linklistp temp = head;

    while (temp->next != NULL) {

        temp = temp->next;

        count ++;

    }

    return count;

    

}


然后实现指定位置插入元素的函数

/**

 指定位置插入

 */

linklistp insertAtIndex(linklistp head,int index,linklistp newNode){

   

    if(head == NULL){

        return head;

    }

    int length = getLength(head);

    //Tips:超出链表范围,直接返回

    if(index >= length+1 || index < 0) {

        return head;

    }

    //Tips:如果是在头结点前面插入

    if(index == 0){

        

        return insert_head(head, newNode);

    }

    //Tips:如果是在尾节点后面插入

    if(index == length){

        

        return insert_tail(head, newNode);

        

    }

    

    //Tips:先找到要插入位置的前一个元素,并且找到该元素的后继,然后将前一个元素的next指针指向待插入            的元素,待插入的元素的next指针指向刚才我们找到的后继,这样插入操作就完成了

    linklistp temp = head;

    for(int i = 0; i <= length; i ++){

        

        if(i == index-1){

            

            linklistp nextNode = temp->next;

            temp->next = newNode;

            

            newNode->next = nextNode;

            break;

            

        }

        temp = temp->next;

        

    }

    return head;

    

}


下面再来定义删除指定元素的操作

/**

 删除指定节点

 */

linklistp deleteAtIndex(linklistp head,int index){

   

    if(head == NULL){

        return head;

    }

    int length = getLength(head);

    if(index < 0 || index > length){

        return head;

    }

    //Tips:如果要删除的是头结点,那么把链表头结点变成原头结点后继,删除原头结点

    linklistp temp = head;

    if(index == 0){

        head = temp->next;

        free(temp);

        return head;

    }

    //Tips:删除的时候先找到要删除元素的前一个元素temp,让前一个元素temp的next指向要删除位置的元素            的后继,然后释放被删除的元素

    for(int i = 0; i < length; i ++){

        

        if(i == index-1){

            linklistp nextNode = temp->next->next;

            temp->next = nextNode;

            free(temp);

            

            break;

        }

        temp = temp->next;

    }


    return head;

}


最后再写一个函数输出链表的所有元素

/**

 输出链表元素

 */

void outPut(linklistp head){

    

    linklistp temp = head;

    while (temp) {

        

        printf("%d\n",temp->data);

        temp = temp->next;

    }

    

}

这样就可以进行操作删除的验证了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值