首页 > 编程知识 正文

不带头节点单链表为空,单链表不是一种随机存储结构

时间:2023-05-03 23:36:11 阅读:117322 作者:2190

单链表结构后的*List是指向结构的指针类型,它定义了该类型的指针。

例如,List p; 该p是指向链接列表结构的指针,是单链表的头指针。 (因此,请注意,虽然头部指针必然存在,但单链表中不一定有头部节点,因此要区分头部指针和头部节点。)

类型defstructlinkedlist { int data; //数据域结构链接列表*下一步; //指针字段,指定中继节点,存储中继节点的地址}*List; //List==List *,其中List是单链接列表的开头指针

初始化没有开头节点和开头节点的初始化开头节点的单链表的初始化。 头下一个=空; 开头节点的data数据字段用于记录链表的长度时,必须初始化为0 head-data=0。

//申请头部节点或初始化空表list create _ head _ node ({ listhead=(list ) malloc (sizeof (链接的列表) } ); //创建第一个节点(第一个节点的单链表(if ) head==0) ) /节点空间申请失败时,此判断语句判断是否存在返回空值}head-next=NULL; ////head是head的地址,h-next是head-next的地址,该地址是第一个节点的地址,如果地址为NULL,则可以不操作空表////head-data,但可以不操作head-data 头数据=0; 返回头; }初始化没有开头节点的单链表

List link_list_create () {List p; p=空值; 返回p; }

求链表长度的单链表长度有两种方法

在第一个节点的data数据字段中记录链表的长度(仅适用于第一个节点的链表)。 创建头部节点时,头部节点的data初始化为0。 插入操作成功后,标题数据字段1。 删除操作成功后,头节点数据字段-1。 时间复杂度为o(1),)因此链表的第一节点推荐这种方式),头数据=0; 00在头数据中初始化头数据数据字段; 每次插入//元素时,标头节点数据字段1head-data--; //每次删除一个元素时,标题节点数据字段-1head-data; 获取//链表的长度遍历链表获取长度。 时间复杂度为o(n )//长度intlink_list_length(listhead ) {List p=head-next; int len=0; while(p ) {len; p=p-next; }返回len; }

空表判断为带头结点的空表判断head为head节点、h-next为head节点的地址、该地址为第一个节点的地址、地址为NULL,为空表boolean isission }或(如果要使用头部节点数据字段记录链表的长度,可以使用此方法)布尔输入列表(if ) (p-data==0) {返回真; }返回假; } 不带头结点的空表判断p==NULL; p表示第一个节点的地址,p=NULL表示第一个节点的地址为空,即空表booleanisempty(listp ) if ) p=NULL ) {return TRUE; }返回假; }

头插入法在链表的头插入节点,即作为链表的第一个元素,时间复杂度为o(1)

//booleanhead_insert(listhead,int x ) ) listp=(list ) malloc (sizeof ) linkedlist ) ); //申请节点,将要插入的元素填充到该节点的数据域p-data=x中; p-next=head-next; 头下一步=p; 头数据; //节点插入成功,链表长度1return TRUE; }

末尾插入法在链表的末尾插入节点,即作为链表的最后一个元素,时间复杂度为o(n )。

新结点插入链表尾部时,新结点的next域必须置为空,即:newNode-next = NULL;单链表末尾节点的next域必须为null,因此调用末尾节点的next指针p-next时,如果确定末尾节点的next没有值,则动态不是清空next域。 通常不会出现问题,但如果遍历链表、获取每个内容的节点或第二次将其作为节点插入,则程序将

会陷入死循环,最终耗尽cpu性能。你可以将tail_insert()方法中的newNode->next = NULL;这行代码注释掉,然后调用我们后面讲到的show()方法进行测试,你就会看到show()方法会不停息的打印输出一个个未知地址,直至内存耗尽,系统奔溃

//尾插boolean tail_insert(List head, int x) {List newNode = (List)malloc(sizeof(LinkedList)); //申请一个结点,并将要插入的元素填入该结点的数据域newNode->data = x;//newNode->next是动态分配的,如果你不置为空,系统就会动态地给它分配一个未知地址。newNode->next = NULL;List p = head; //用p结点做记录while (p->next != NULL) { //遍历链表,直至尾结点p = p->next;}p->next = newNode; //让尾结点指针,指向新结点head->data++; //新结点插入成功,链表长度+1return TRUE;}



指定位置插入 在第k个位置插入新结点。需要先遍历链表,找到第k-1个结点,然后再修改新结点指针和第k-1个结点的指针,即可实现在第k个位置插入新结点操作。
//指定位置插入boolean insert(List head, int k, int x) {if (k < 1) {printf("插入位置非法!");return FALSE;}List p = head;int i = 0; //用i来记录结点位置while (p->next != NULL && i < k - 1) {i++;p = p->next;}if (i + 1 == k) {List tmp = (List)malloc(sizeof(LinkedList)); //申请一个结点,并将要插入的元素填入该结点的数据域tmp->data = x;tmp->next = p->next;p->next = tmp;head->data++; //新结点插入成功,链表长度+1return TRUE;} else {printf("插入位置非法!");return FALSE;}}



按位序查找 //按位序查找List get(List head, int k) {if (k < 1) {printf("查找位置非法!");return NULL;}List p = head;int i = 0;while (p->next != NULL && i < k) { //找到第k个结点i++;p = p->next;}if (i == k) { //判断i是否等于要查找结点的位序return p;}else{printf("查找位置非法!");return NULL;}}



删除第1个结点 //删除第1个结点boolean del_first(List head) {if (head->next != NULL) {head->next = head->next->next; //让头结点next指针,指向头结点下一个结点的next指针所致地址head->data--; //链表长度减1return TRUE;}return FALSE;}



删除第k个结点 //删除第k个结点boolean del(List head, int k) {List p = head;if (p->next == NULL && k < 1) {printf("删除位置非法!n");return FALSE;}int i = 0; //用i记录结点位置while (p->next != NULL && i < k - 1) { //找到待删结点的前一个结点i++;p = p->next;}if (i + 1 == k) { //判断i是不是k结点的前一个结点的位置p->next = p->next->next;head->data--; //链表长度减1return TRUE;} else {printf("删除位置非法!n");return FALSE;}}



遍历链表,显示数据 前面讲到了,如果在新结点插入链表尾部时,如果新结点next指针没有置为NULL,则在show()遍历链表时,将链表的结点数据输出后,方法不会中断,而是继续输出一个个未知地址,直至内存空间耗尽。 //显示数据void show(List head) {List p = head->next;while (p != NULL) {printf("%d ", p->data);p = p->next;}}



全部代码 #include <stdio.h>#include <stdlib.h> //malloc需要此头文件typedef enum {FALSE, TRUE} boolean;//结构体typedef struct LinkedList {int data;struct LinkedList *next;} *List; //List <==> List *//申请一个头结点,并初始化List create_head_node() {List head = (List)malloc(sizeof(LinkedList)); //创建头结点,并让头指针指向头结点 (带头结点单链表)if (head == 0) { //结点空间申请失败,该判断语句可有可无return NULL;}head->next = NULL; //head表示的是头结点的地址,h->next就是头结点的下一个结点,即第一个结点的地址为空,也就是空表//head->data不用操作,但若想用头结点数据域保存链表长度,可以设置为head->data = 0;head->data = 0;return head;}//头插boolean head_insert(List head, int x) {List p = (List)malloc(sizeof(LinkedList)); //申请一个结点,并将要插入的元素填入该结点的数据域p->data = x;p->next = head->next;head->next = p;head->data++; //结点插入成功,链表长度+1return TRUE;}//尾插boolean tail_insert(List head, int x) {List newNode = (List)malloc(sizeof(LinkedList)); //申请一个结点,并将要插入的元素填入该结点的数据域newNode->data = x;//newNode->next是动态分配的,如果不置为空,系统就会默认分配一个未知地址newNode->next = NULL;List p = head; //用p结点做记录while (p->next != NULL) { //遍历链表,直至尾结点p = p->next;}p->next = newNode; //让尾结点指针,指向新结点head->data++; //新结点插入成功,链表长度+1return TRUE;}//指定位置插入boolean insert(List head, int k, int x) {if (k < 1) {printf("插入位置非法!");return FALSE;}List p = head;int i = 0; //用i来记录结点位置while (p->next != NULL && i < k - 1) {i++;p = p->next;}if (i + 1 == k) {List tmp = (List)malloc(sizeof(LinkedList)); //申请一个结点,并将要插入的元素填入该结点的数据域tmp->data = x;tmp->next = p->next;p->next = tmp;head->data++; //新结点插入成功,链表长度+1return TRUE;} else {printf("插入位置非法!");return FALSE;}}//按序号查找List get(List head, int k) {if (k < 1) {printf("查找位置非法!");return NULL;}List p = head;int i = 0;while (p->next != NULL && i < k) { //找到第k个结点i++;p = p->next;}if (i == k) {return p;} else {printf("查找位置非法!");return NULL;}}//删除第1个结点boolean del_first(List head) {if (head->next != NULL) {head->next = head->next->next;head->data--;return TRUE;}return FALSE;}//删除第k个结点boolean del(List head, int k) {List p = head;if (p->next == NULL && k < 1) {printf("删除位置非法!n");return FALSE;}int i = 0; //用i记录结点位置while (p->next != NULL && i < k - 1) { //找到待删结点的前一个结点i++;p = p->next;}if (i + 1 == k) { //判断i是不是k结点的前一个结点的位置p->next = p->next->next;head->data--;return TRUE;} else {printf("删除位置非法!n");return FALSE;}}//显示数据void show(List head) {List p = head->next;while (p != NULL) {printf("%d ", p->data);p = p->next;}}int main() {List head = create_head_node();printf("当前单链表长度为:%dnn", head->data);head_insert(head, 15);head_insert(head, 25);head_insert(head, 35);printf("第1个结点元素为:%dn", get(head, 1)->data);printf("第2个结点元素为:%dn", get(head, 2)->data);printf("第3个结点元素为:%dn", get(head, 3)->data);printf("当前单链表长度为:%dnn", head->data);tail_insert(head, 45);tail_insert(head, 55);printf("第1个结点元素为:%dn", get(head, 1)->data);printf("第2个结点元素为:%dn", get(head, 2)->data);printf("第3个结点元素为:%dn", get(head, 3)->data);printf("第4个结点元素为:%dn", get(head, 4)->data);printf("第5个结点元素为:%dn", get(head, 5)->data);printf("当前单链表长度为:%dnn", head->data);insert(head, 6, 65);insert(head, 2, 75);printf("第1个结点元素为:%dn", get(head, 1)->data);printf("第2个结点元素为:%dn", get(head, 2)->data);printf("第3个结点元素为:%dn", get(head, 3)->data);printf("第4个结点元素为:%dn", get(head, 4)->data);printf("第5个结点元素为:%dn", get(head, 5)->data);printf("第4个结点元素为:%dn", get(head, 6)->data);printf("第5个结点元素为:%dn", get(head, 7)->data);printf("当前单链表长度为:%dnn", head->data);show(head);printf("nn");del_first(head);show(head);printf("nn");del(head, 4);show(head);return 0;}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。