单链表基本操作(含头结点)

2019-08-18  本文已影响0人  mark_x
链表基本结构
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct Node
{
    int value;
    struct Node *next;
}Node;
typedef struct Node *LinkList;


void createListHead(LinkList *L, int n)
{
    LinkList p;
    int i;
    
    srand(time(0));
    
    *L = (LinkList)malloc(sizeof(Node));   // 修改头指针的值,指向创建的头结点
    (*L)->next = NULL;  // 注意不能是L->next  L是头指针,头指针没有next元素,是头指针指向的头结点的next
    
    for (i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));
        p->value = rand() %100+1;
        p->next = (*L)->next;
        (*L)->next = p;
    }
}

void createListTail(LinkList *L, int n)
{
    LinkList p, r;
    int i;
    
    *L = (LinkList)malloc(sizeof(Node));
    r = *L;
    
    
    for (i=0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));
        p->value = 1001+i;
        r->next = p;
        r = p;
    }
    r->next = NULL;
    
}



void printList(LinkList *L)
{
    LinkList p;
    p = (*L)->next;
    
    while (p)
    {
        printf("%d  ", p->value);
        p = p->next;
    }
    printf("\n");
}


int getElem(LinkList *L, int posi)
{
    LinkList p;
    p = (*L)->next;  // 因为L是头结点,不存数据,next才是第一个数据节点

    
    int count = 1;
    while (p && count < posi)
    // 初始状态p为1号节点 p->value就是一号节点的数据
    {
        p = p->next;
        count++;
    }
    if (!p)  // 如果往前一直推进到了p指向NULL,说明没有找到对应位置,说明posi超出链表范围
    {
        printf("查找位置无效!\n");
        return 0;
    }
    return p->value;

}


void insertList(LinkList *L, int posi, int num)
{
    LinkList p;
    p = *L;  // 注意:初始化为头结点 
    
    int count = 1;
    while (p && count < posi)
    {
        p = p->next;
        count++;
    }
    if (!p)
    {
        printf("插入位置无效!\n");
    }
    else
    {
        LinkList new;
        new = (LinkList)malloc(sizeof(Node));// 通过设置头结点实现了在头尾插入元素与中间插入元素的代码上的一致性
        new->value = num;                    // 如posi=1(头部),不执行循环,p指向头结点
                                             // 如posi=11(尾部),退出循环后,p指向10号位置,此时p->next就是NULL
        new->next = p->next;  
        p->next = new;        
    }
    
}

int delElem(LinkList *L, int posi)
{
    LinkList p, q;
    p = *L;
    
    int count = 1, num = 0; // num用来返回删除的数
    while (p && count < posi) //
    {
        p = p->next;
        count++;
    }
    if (!p)
    {
        printf("删除位置无效!\n");
    }
    else
    {
        
        q = p->next;
        num = q->value;
        
        p->next = q->next;
        free(q);
    }
    return num;
    
}

void delList(LinkList *L)
{
    LinkList p, q;
    p = (*L)->next;
    
    while (p)
    {
        q = p->next;
        free(p);
        p = q;
    }
    (*L)->next = NULL;

}

int main()
{
    LinkList Lp = NULL;
    // 单链表的创建
    createListTail(&Lp, 10);
    
    printList(&Lp);
    
    // 单链表的读取
    int num;
    num = getElem(&Lp, 2);
    printf("第2个元素的值是:%d\n", num);
    
    // 单链表的插入
    int posi = 1;
    num = 520;
    insertList(&Lp, posi, num);
    printf("在%d号位置插入了数值%d\n", posi, num);
    printList(&Lp);
    
    // 单链的删除
    posi = 10;
    num = delElem(&Lp, posi);
    printf("删除了%d号元素:%d\n", posi, num);
    
    printList(&Lp);
    
    // 整表删除
    delList(&Lp);
    printf("已删除链表!\n");
    printf("打印删除后的链表...\n");
    printList(&Lp);
    
    
    
    return 0;
}

上一篇 下一篇

猜你喜欢

热点阅读