单链表双指针实现

单链表的实现思想和双指针的应用方法在前面博客中都已阐述,在本文将实现双指针实现单链表的初始化,插入,删除,打印。

【测试代码1】

#include<stdio.h>
#include<stdlib.h>

typedef  struct Node{
    int data;
    struct Node *next;
}node_t;

//创建头结点
node_t * create()
{
    node_t *head = (node_t *)malloc(sizeof(node_t));
    head->next = NULL;

    return head;
}
void insert(node_t **list, int data)
{
    node_t *pnode = (node_t *)malloc(sizeof(pnode));
    pnode->data = data;
    pnode->next = NULL;

    if(*list == NULL)
    {
        *list = pnode;
    }
    else
    {
        node_t *p =*list;
        while(p->next != NULL)
        {
            p = p->next;
        }
        p->next = pnode;
    }
}

void remove(node_t **list, int data)
{
    node_t *p =( *list);

    if(p ->next== NULL)
        return ;
    while(p->next->data != data)
        p = p->next;
    if(p->next == NULL)
        printf("no data");
    if (p->next->data == data)
        p->next = p->next->next;

}

void print(node_t **list)
{

    node_t *p = (*list)->next;

    if(!p)
        return;
    while(p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }

}
void main()
{

    node_t *head;//链表头结点
    node_t **list;//链表头指针
    head = create();
    list =& head;//令链表头指针指向头结点
    insert(list,1);
    insert(list,2);
    insert(list,3);
    insert(list,4);
    insert(list,5);
    insert(list,6);
    printf("after insert data, the list data is:\n");
    print(list);
    printf("\n");
    printf("remove data 6, the list data is:\n");
    remove(list,6);
    print(list);
}

【输出结果】

这里采用尾部插入,所以头指针始终指向头结点,双指针的用处就是你可以改变其头结点后面的内容,而不会改变头指针的位置,如果是前部插入的话,需要不断变化头结点的位置,程序会有所区别。

【测试代码2】

#include<stdio.h>
#include<stdlib.h>

typedef  struct Node{
    int data;
    struct Node *next;
}node_t;

//使得头指针指向头结点
node_t * create()
{
    node_t *head = (node_t *)malloc(sizeof(node_t));
    head->next = NULL;

    return head;
}
void insert_front(node_t **list, int data)
{
    node_t *pnode = (node_t *)malloc(sizeof(pnode));
    pnode->data = data;
    pnode->next = (*list)->next;
    (*list)->next = pnode;
}

void remove(node_t **list, int data)
{
    node_t *p =( *list);

    if(p ->next== NULL)
        return ;
    while(p->next->data != data)
        p = p->next;
    if(p->next == NULL)
        printf("no data");
    if (p->next->data == data)
        p->next = p->next->next;

}

void print(node_t **list)
{

    node_t *p = (*list)->next;

    if(!p)
        return;
    while(p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }

}
void main()
{

    node_t *head;
    node_t **list;
    head = create();
    list =& head;
    insert_front(list,1);
    insert_front(list,2);
    insert_front(list,3);
    insert_front(list,4);
    insert_front(list,5);
    insert_front(list,6);
    printf("after insert data, the list data is:\n");
    print(list);
    printf("\n");
    printf("remove data 6, the list data is:\n");
    remove(list,6);
    print(list);
}

【输出结果】

时间: 2024-12-15 07:09:22

单链表双指针实现的相关文章

数据结构关于单链表的一些操作的源代码

单链表的可以有许多问题,这是我特意整理一下的有关他的相关操作,给出代码,有需要的可以自己调试,重要的就是关于环的一些操作: #include <iostream>#include <cstdio>#include <cstdlib>#include <ctime>using namespace std;typedef int Elemtype;typedef struct Node{ Elemtype data; struct Node *next;}Nod

java单链表常用操作

总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K个节点] [查找链表中间节点] [判断链表是否有环] [从尾到头打印单链表-递归] [从尾到头打印单链表-栈] [由小到大合并有序单链表-循环] [由小到大合并有序单链表-递归] 通常在java中这样定义单链表结构 <span style="font-family:Microsoft YaHe

Java-反转单链表

单链表的反转比较简单,迭代和递归都可以做. 先定义一个类用于表示单链表中的结点: public class ListNode { private int val; private ListNode next; public ListNode(int value){ this.val = value; this.next = null; } public int getVal() { return val; } public void setVal(int val) { this.val = va

C语言写单链表的创建、释放、追加(即总是在最后的位置增加节点)

昨天周末给学妹讲了一些指针的知识,本来我对指针就是似懂非懂的状态,经过昨天一讲,我对指针的学习就更深刻了果然给别人讲课也是学习的一个方法.加上最近复习数据结构,发现我的博客里没有链表的博文,所以趁这时候加上一篇. 在此之前,我们先谈一下我要说的一些基本知识: ①函数参数为什么是双指针? 我们先写一下这么一个程序: # include<stdio.h>void Gai(int m){ m=5;}int main(void){ int a=1; Gai(a); printf("%d\n&

单链表相关问题

/* 判断单链表是否存在环 1)暴力:双层循环遍历(n^2) 2)双指针:快指针fast=NULL,慢指针slow=NULL int judge(link head) { if(NULL==head) return false; link fast = head, slow = head; while(slow!=NULL && fast!=NULL) { slow = slow->next; fast = fast->next->next; if(slow==fast)

剑指offer—单链表反转的三种实现方法

单链表的反转可以用递归.非递归和栈的方法实现 链表节点定义: struct ListNode{ int val; Node* next; ListNode(int x):val(x),next(nullptr){} } 1.栈 ListNode* reverseList(ListNode* head) { if(!head || !head->next) return head; stack<ListNode*>stk; //将链表的结点全部压进栈 while(head){ stk.pu

单链表逆置

重写单链表逆置,熟能生巧- #include <iostream> #include <cstdlib> using namespace std; typedef struct List{ int num; struct List *next; }ListNode,*pListNode; void display(ListNode *pHead) { while(pHead) { cout<<pHead->num<<"--"; pH

02 单链表

线性表之链式存储---单链表 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 // 数据结构 6 typedef struct node 7 { 8 int data; 9 struct node *next; 10 }linkList; 11 12 // 创建单链表,并初始化 13 linkList *linkList_init(void) 14 { 15 linkList *l

(单链表)单链表的整体逆序和局部逆序

题目一:将单链表翻转. 思路:有三种方式. 一:用数组存储单链表的值,然后重新逆序赋值,效率较低. 二:利用三个指针,在原来的基础上进行逆序.这种方法比较实用,效率也高. 三:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾.需要新建一个链表,这种方法和第二种差不多. 这里我就写出第二种方法,比较实用. 代码(方法二): struct ListNode { int val; ListNode *next; ListNode(int x) :