C 无头结点单链表若干操作

顾名思义就是从一开就是有用的结点

定义结构体

typedef struct Node {
    int element;
    struct Node *next;
}LNode, * LinkNode;

创建

这里是手输入,输入为0的时候就退出来

//传入一个头指针的地址
void create(LinkNode *head){
	//这里就用p1, p2循环插入即可
    LinkNode p1, p2;
    p1 = p2  = (LinkNode)malloc(sizeof(LNode));
    (*head) = NULL;
    //先创建一个结点
    int a, n = 0;
    scanf("%d", &a);
    p1->element = a;
    //当结构体的值不为零的时候就循环往复地走
    while (p1->element != 0) {
        n++;
        if(n == 1){
        	//要是第一个结点特别标记
            *head = p1;
        }else{
        	//要不是第一个节点的话,上次循环中新创建的p1就成为链表最后一个节点
            p2->next = p1;
        }
        //将p2指向最后一个节点
        p2 = p1;
        //新创建一个节点,初始化,这个还没判断a是不是等于零先放着
        p1 = (LinkNode)malloc(sizeof(LNode));
        scanf("%d", &a);
        p1->element = a;
    }
    //循环结束,就不再
    p2->next = NULL;
}

输出链表的值

void putout(LinkNode p){
    while (p) {
        printf("%d", p->element);
        p = p->next;
    }
    printf("\n");
}

在第i个位置前插入

要是空的链表将其视为第一个,要是i比整个链表都要大那就加在最后一个

//在第i个位置前插入元素e
void insertElemnt(LinkNode * p, int i, int e) {
    int n = i;
   	//先创建两个节点,p1指向最新的,p2指向p1的前一个
    LinkNode p1 = *p, p2 = NULL;
    //创建一个待插入的节点
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    //如果链表整体为空,那插入的就是第一个了
    if(p1 == NULL){
        *p = insertE;
    }
    /*如果在最前面插入的话,那就头结点就是新插入的这个,原来的头结点
    退居第二个*/
    else if (n == 1)
    {
        *p = insertE;
        insertE->next = p1;
    }
    //一般的情况
    else{
    	//前提是插入节点的前面的那个节点不能为空
        while (p1) {
        	//要是n=1,那就找对了位置,出来就可以了,那么p1就是第n个
            if(n == 1) break;
            //p2总也是p1的前面那个节点
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        //进行插入,在p2和p1之间将其插进去
        p2->next = insertE;
        //p1有可能为空,为空就让其等于NULL
        insertE->next = p1 ? p1 : NULL;
    }
}

删除第i个节点

要是空的链表返回,要是i比整个链表都要大那就删除最后一个

void deleteElement(LinkNode *p, int i){
	if(!*p) return;
	//还是原来的样子找p1就是该删的,p2是p1的前一个
    LinkNode p1 = *p, p2 = NULL;
    int n = i;
    //要是在第一个的话,头指针后移一位
    if(n == 1){
        *p = p1->next;
    }else
    {	
    	//一直循环直到最后一个
        while (p1->next) {
        	//到位置了
            if(n == 1) break;
            //p2就是p1的前面那个
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        /*要是p2后面还有内容,p2就不是最后一个,说明p1就是第i个,i合法
        如果i不合法,p1就是最后一个跳出来了,那就删除最后一个就好了,
        其实这里可以判断n的值是不是等于1,就可以知道是i不合法还是到
        位置了*/
        if(p2->next) {
            p2->next = p1->next;
        }
        //如果只有一个的话,那就都删了;
        if(*p == p1){
            *p = NULL;
        }
        //释放p1;
        free(p1);
    }
}

头插法

//头插法
void headInsert(LinkNode *p, int e){
	//每次也都是在第一个节点插入,我只需记录第一个节点,新的节点指向他就好了
    LinkNode p1 = *p;
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    
    *p = insertE;
    insertE->next = p1;
}

尾插法

//尾插法
void tailInsert(LinkNode *p, int e){
    //我新建一个节点
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    //遍历到最后一个节点
    LinkNode p1 = *p;
    while (p1->next) {
        p1 = p1->next;
    }
    //p1就是最后一个节点,就此往后只一个就OK了
    p1->next = insertE;
}

完整程序代码

//
//  main.c
//
//  Created by 赫凯 on 2018/10/21.
//  Copyright © 2018年 赫凯. All rights reserved.
//

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

typedef struct Node {
    int element;
    struct Node *next;
}LNode, * LinkNode;

//创建结构体
void create(LinkNode *head){
    LinkNode p1, p2;
    p1 = p2  = (LinkNode)malloc(sizeof(LNode));
    (*head) = NULL;
    
    int a, n = 0;
    scanf("%d", &a);
    p1->element = a;
    
    while (a != 0) {
        n++;
        if(n == 1){
            *head = p1;
        }else{
            p2->next = p1;
        }
        p2 = p1;
        
        p1 = (LinkNode)malloc(sizeof(LNode));
        scanf("%d", &a);
        p1->element = a;
    }
    p2->next = NULL;
}

//输出单链表
void putout(LinkNode p){
    while (p) {
        printf("%d ", p->element);
        p = p->next;
    }
    printf("\n");
}

//单链表访问第i个元素
int find(LinkNode p, int i){
    LinkNode p1 = p;
    int j = 1;
    while (p1) {
        if(j == i){
            return p1->element;
        }
        j++;
        p1 = p1->next;
    }
    return 0;
}
//在第i个位置前插入元素e
void insertElemnt(LinkNode * p, int i, int e) {
    int n = i;
    
    LinkNode p1 = *p, p2 = NULL;
    
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    
    if(p1 == NULL){
        *p = insertE;
    }else if (n == 1)
    {
        *p = insertE;
        insertE->next = p1;
    }
    else{
        while (p1) {
            if(n == 1) break;
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        p2->next = insertE;
        insertE->next = p1?p1:NULL;
    }
}

//删除第i个元素
void deleteElement(LinkNode *p, int i){
    LinkNode p1 = *p, p2 = NULL;
    int n = i;
    if(n == 1){
        *p = p1->next;
    }else
    {
        p2 = p1;
        while (p1->next) {
            if(n == 1) break;
            p2 = p1;
            p1 = p1->next;
            n--;
        }
        
        if(p2->next) {
            p2->next = p1->next;
        }
        if(*p == p1){
            *p = NULL;
        }
        free(p1);
    }
}
//头插法
void headInsert(LinkNode *p, int e){
    LinkNode p1 = *p;
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    
    *p = insertE;
    insertE->next = p1;
}
//尾插法
void tailInsert(LinkNode *p, int e){
    
    LinkNode insertE = (LinkNode)malloc(sizeof(LNode));
    insertE->element = e;
    insertE->next = NULL;
    
    LinkNode p1 = *p;
    while (p1->next) {
        p1 = p1->next;
    }
    p1->next = insertE;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    LinkNode head;
    create(&head);
    putout(head);
    
    printf("%d",find(head, 2));
    
    printf("\n");
    
    insertElemnt(&head, 3, 4);

    putout(head);
    deleteElement(&head, 3);
    putout(head);
    int i;
    for (i = 1; i < 8; i++) {
        headInsert(&head, i);
        tailInsert(&head, i);
    }
    putout(head);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赫凯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值