链表学习
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表学习相关的知识,希望对你有一定的参考价值。
最近看了一小部分《大话数据结构》对链表的部分有了更深刻的认识,这本书真的挺不错,很能吸引读者,不会枯燥。链表部分,之前有过学习,但并没有深入,当时还感觉链表也就那么回事,做题时有个插入节点的,当时想法是对的,但细节有问题,因而一直没能做成功。
进行插入操作时,我当时想法是这样的(伪代码):
- /* 假设已经创建了一个链表 LinkList */
- int linkListInsert(int i)
- {
- int j;
- LinkList *s;
- p=head; /*全局变量*/
- j=1;
- while(p && j<i) /*遍历链表*/
- {
- p = p -> next;
- j++;
- }
- if(!p || j>i)
- return 0;
- s = (LinkList *) malloc (sizeof (LinkList) );
- enter >> (s -> LinkElem); /* (伪代码) 向该节点数据域输入数据 */
- p -> next = s;
- s -> next = p -> next; /* 正好犯了书中指出的错误 */
- /* 这里上一个链表节点指向的后一个节点被赋予了新地址,并存放了数据。下一步,s -> next = p -> next; 的作用是将上一个节点的后面接上新节点(因为原本 p 是指向 p ->next的 即 p = p -> next),但因为 p -> next = s; 所以 s -> next = s; 也就是说将会出现 p = s;而没有了后继元素。*/
- return 1;
- }
- p -> next = s;
- s -> next = p -> next;
这部分是差不多的,但是是错误的。
其他的删除节点、获取某节点上的元素什么的都比较简单,也就不用细究了。
最后附上自己学习这部分后完整实现创建链表、插入节点、删除节点、获取某节点元素的代码(因为书上好像没有完整的代码,只有部分功能片段代码)
代码如下:
#include <stdio.h> #include <time.h> #include <conio.h> #include <stdlib.h> #define INITIA 5 typedef int ElemType; typedef int Status; typedef struct Node { ElemType data; struct Node * next; }node; node * head = NULL, *p, *q; Status GetElem(); Status LinkListInsert(); Status LinkListDelete(); //获取某个地址的元素 Status GetElem(int i, ElemType e) { int j; p = head; j = 1; while(p && j < i) { p = p -> next; ++j; } if(!p || j > i) return 0; e = p -> data; printf("%d",p -> data); return 1; } //向链表某位置插入节点 Status LinkListInsert(int i) { int j; node * s; p = head; j = 1; while(p && j < i) { p = p ->next; ++j; } if(!p || j > i) return 0; s = ( node * ) malloc ( sizeof ( node ) ); s -> data = rand()%100 + 1; s ->next = p -> next, p -> next = s ; return 1; } //删除链表某节点 Status LinkListDelete(int i, ElemType e) { int j; node * s; p = head; j = 1; while(p && j < i - 1) //这里书中是 j < i,这样写会有什么变化,感兴趣的可以自己改一下试试 { p = p -> next; ++j; } if(!p || j > i) return 0; s = p -> next; p -> next = p -> next -> next; e = s -> data; free(s); return 1; } int main() { char str; int i; ElemType e = 0; srand ( time( 0 ) ); for(i = 0; i < INITIA; i ++) { p = ( node * ) malloc ( sizeof ( node ) ); if(head == NULL) head = p; else q ->next = p; p -> next = NULL; p -> data = rand()%100 + 1; q = p; } p = head; while(p) { printf("%d ",p -> data); p = p -> next; } printf("\n查找 请按 1 插入数据 请按 2 删除数据 请按 3"); str = getch(); if(str == ‘1‘) { printf("\n请输入要查找的数的位置:"); scanf("要查找的数为:%d\n",&i); GetElem(i, e); } if(str == ‘2‘) { printf("\n请输入要插入的数的位置:"); //插在原本该位置上数据的后一位
scanf("%d",&i); LinkListInsert(i); p = head; while(p) { printf("%d ",p -> data); p = p -> next; } } if(str == ‘3‘) { printf("\n请输入要删除的数的位置:"); scanf("%d",&i); LinkListDelete(i, e); p = head; while(p) { printf("%d ",p -> data); p = p -> next; } } return 0; }
以上是关于链表学习的主要内容,如果未能解决你的问题,请参考以下文章
NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段