前言
顺序表的存贮特点是用物理上的相邻实现了逻辑上的相邻,它要求用连续的存储单元顺序存储线性表中各元素,因此,对顺序表插入、删除时需要通过移动数据元素来实现,影响了运行效率。
这里介绍线性表链式存储结构,它不需要用地址连续的存储单元来实现,因为它不要求逻辑上相邻的两个数据元素物理上也相邻,它是通过“链”建立起数据元素之间的逻辑关系来,因此对线性表的插入、删除不需要移动数据元素。
链表
链表是通过一组任意的存储单元来存储线性表中的数据元素的,那么怎样表示出数据元素之间的线性关系呢?
为建立起数据元素之间的线性关系,对每个数据元素ai,除了存放数据元素的自身的信息ai 之外,还需要和ai一起存放其后继ai+1 所在的存贮单元的地址,这两部分信息组成一个“结点”,结点的结构如图2.6 所示,每个元素都如此。
存放数据元素信息的称为数据域,存放其后继地址的称为指针域。
因此n个元素的线性表通过每个结点的指针域拉成了一个“链子”,称之为链表。
因为每个结点中只有一个指向后继的指针,所以称其为单链表。
#include <stdio.h> #include<malloc.h> //声明链表节点类型 typedef struct LISTtag LISTtagNode; struct LISTtag{ int value; LISTtagNode *next; }; //创建链表 LISTtagNode * create(){ LISTtagNode *head; head = (LISTtagNode*)malloc(sizeof(LISTtagNode)); head->next = NULL; return head; } //在链表尾新增节点 int LinKListInsertbottom(LISTtagNode *head,int value){ if(head == NULL){ return -1; } //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点为最后一个节点 node->value = value; node->next = NULL; LISTtagNode *t = head; //找到尾指针 while (t->next != NULL) { t = t->next; } t->next= node; return 1; } //在链表头新增节点 int LinKListInserttop(LISTtagNode *head,int value){ if(head == NULL){ return -1; } //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; return 1; } //打印链表 int PrindLinKList(LISTtagNode *head){ if(head == NULL){ return -1; } LISTtagNode *t = head; while (t->next != NULL) { t = t->next; printf("%d ", t->value); } return 1; } //修改某个位置的值 int update(LISTtagNode *head,int index,int value){ if(head == NULL){ return -1; } LISTtagNode *t = head; int i = 0; //要么是最后一个节点,要么超出index while ((t->next != NULL)&&(i<index)) { t = t->next; i++; } //1.t->next ==NULL,退出循环,i<index不满足情况 //2.i>=index,退出循环,t->next != NULL不满足情况 //3.上面两种情况同时发生 //如果为最后一个节点或者超出index才会执行下列语句 if(i == index && i != 0 ){//i != 0,头节点没有存储数据 t->value = value; } return 1; } int main () { LISTtagNode *head = create(); LinKListInsertbottom(head,7); LinKListInserttop(head,22); LinKListInsertbottom(head,3); LinKListInsertbottom(head,43); LinKListInsertbottom(head,32); LinKListInsertbottom(head,42); LinKListInsertbottom(head,12); LinKListInsertbottom(head,14); LinKListInsertbottom(head,14); printf(" 正序打印链表:"); PrindLinKList(head); return 0; }