链表

链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
在这里我们直接来看案例:

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


// 创建链表
// data,数据数组
// data_length,数组长度
struct LinkList *linklist_create(int data[], int data_length)
{
	struct LinkList *head;
	struct LinkList *tail;
	int i;

	// 创建并初始化头结点
	head = (struct LinkList *)malloc(sizeof(struct LinkList));
	head->id = -1;
	head->next = NULL;

	tail = head;
	for (i = 0; i < data_length; i++) {
		// 1)创建节点并初始化
		struct LinkList *node;
		node = (struct LinkList *)malloc(sizeof(struct LinkList));
		node->id = data[i];
		node->next = NULL;

		// 2)尾结点连接新节点
		tail->next = node;

		// 3)尾结点移动到新节点
		tail = node;
	}

	return head;
}

// 遍历链表,打印
void linklist_printf(struct LinkList *head)
{
	struct LinkList *p;

	// for (i = 0; i < n; i++)
	for (p = head; p != NULL; p = p->next)
	{
		printf("%d\n", p->id);
	}
}

// return 0成功,-1失败
int linklist_delete(struct LinkList *head, int id)
{
	struct LinkList *prev;
	struct LinkList *del;

	prev = head;
	// 1)找到待删除节点的上一个节点
	while(prev != NULL && prev->next != NULL) {
		if (prev->next->id == id) {
			break;
		}

		prev = prev->next;
	}

	// 没找到id
	if (prev->next == NULL) {
		return -1;
	}

	// 2)删除节点
	// 2.1)临时保存待删除节点del
	del = prev->next;

	// 2.2)从链表删除节点del
	prev->next = del->next;

	// 2.3)free del
	free(del);

	return 0;
}

在这个例子中有创建链表和遍历链表。在创建链表中我们创建了struct LinkList *head;
struct LinkList *tail;用来保存头指针和尾指针。尾指针在不断的行进中创建一条链表。在这里插入图片描述在实现遍历的时候也是一样的道理。因为在链表的没有给个结构体中都有着链表中下一个结构体的地址。我们只依次访问便可以遍历链表。我们只要获取头指针的地址即可。
接下来这个是集合创建、删除、添加以及替换的范例
linklist.h

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

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

struct Student {
    int num;
    struct Student *pnext;
};


struct Student * init();
void stuput(struct Student *stu); 
struct Student *delete (struct Student *stu); 
struct Student *jia(struct Student *stu) ;
struct Student *h1(struct Student *stu);
#endif 


demo1.c(名字自己顺手起的)

#ifndef __DEMO1_H__
#define __DEMO1_H__

#include<stdio.h>
#include<stdlib.h>
#include "linklist.h"
struct Student *init() {//链表的初始化
    struct Student *Stu;
    struct Student *head;
    struct Student *node;
    struct Student *tail;
    head = (struct Student *)malloc(sizeof(Stu));
    head->num = 1;
    head->pnext = NULL;
    tail = head;
    int i;
    for (i = 0; i < 4; i++) {
        node = (struct Student *)malloc(sizeof(Stu));
        node->num = i + 2;
        node->pnext = NULL;
        tail->pnext = node;
        tail = node;
    }
    return head;
}

void stuput(struct Student *stu) {//链表的输出
    struct Student *p;
    p = stu;
    int i;
    for (i = 0; p != NULL; i++) {
        printf("num=%d\n ", p->num);
        p = p->pnext;
    }
}

struct Student *delete (struct Student *stu) {//链表的删除
    struct Student *temp;
    struct Student *p;
    int i;
    p = stu;
    temp = (struct Student *)malloc(sizeof(stu));
    temp->num = 0;
    temp->pnext = NULL;
    for (i = 0; p != NULL; i++) {
        if (p->pnext != NULL && p->pnext->num == 3) {
            temp = p->pnext;
            p->pnext = temp->pnext;
            free(temp);
        }
        p = p->pnext;
    }
    return stu;
}

struct Student *jia(struct Student *stu) {//链表的添加
    struct Student *p;
    struct Student *new;
    int i;
    p = stu;
    new = (struct Student *)malloc(sizeof(stu));
    new->num = 0;
    new->pnext = NULL;

    for (i = 0; p != NULL; i++) {
        if (p->pnext != NULL && p->pnext->num == 2) {
            new->pnext = p->pnext;
            p->pnext = new;
            new->num = 9;
            break;
        }
        p = p->pnext;
    }
    return stu;
}

struct Student *h1(struct Student *stu)//链表的替换
{
    struct Student *p;
    struct Studnet *k;
    int i;
    p=stu;
    k=NULL;
    for(i=0;p!=NULL;i++)
    {
        if(p->num==5)
        {
            p->num=44;
        }
        p=p->pnext;
    }
    return stu;
}
#endif

main.c

#include "linklist.h"
int main() {
    struct Student *stu;
    struct Student *p;
    struct Student *k;
    struct Student *u;
    stu = init();
    stuput(stu);
    printf("===");
    p = delete (stu);
    stuput(p);
    printf("===");
    k = jia(stu);
    printf("===");
    stuput(k);
    u = h1(stu);
    printf("===");
    stuput(u);

    return 0;
}

在main.c中,它只负责调用函数。其主要功能由demo1.c内的内容来完成。总的来说,对链表的操作基本上都是基于对与链表的遍历来的。在该范例中,唯独删除与众不同。其余操作皆是需要去遍历链表并寻找符合要求的那一项,并对它进行操作。然而删除却是对目标项的前一项进行操作,由目标项的前一项获取到目标项的地址,并赋值给tmp。由对tmp进行操作,达到删除的目的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值