链表学习

  最近看了一小部分《大话数据结构》对链表的部分有了更深刻的认识,这本书真的挺不错,很能吸引读者,不会枯燥。链表部分,之前有过学习,但并没有深入,当时还感觉链表也就那么回事,做题时有个插入节点的,当时想法是对的,但细节有问题,因而一直没能做成功。

  进行插入操作时,我当时想法是这样的(伪代码):

  1. /* 假设已经创建了一个链表 LinkList */
  2. int linkListInsert(int i)
  3. {
  4.   int j;
  5.   LinkList *s;
  6.   p=head;    /*全局变量*/
  7.   j=1;
  8.   while(p && j<i)  /*遍历链表*/
  9.   {
  10.     p = p -> next;
  11.     j++;
  12.   }
  13.   if(!p || j>i)
  14.     return 0;
  15.   s = (LinkList *) malloc (sizeof (LinkList) );
  16.   enter >> (s -> LinkElem);  /* (伪代码) 向该节点数据域输入数据 */
  17.   p -> next = s;
  18.   s -> next = p -> next;  /* 正好犯了书中指出的错误 */
  19.   /* 这里上一个链表节点指向的后一个节点被赋予了新地址,并存放了数据。下一步,s -> next = p -> next; 的作用是将上一个节点的后面接上新节点(因为原本 p 是指向 p ->next的 即 p = p -> next),但因为 p -> next = s; 所以 s -> next = s; 也就是说将会出现 p = s;而没有了后继元素。*/
  20.   return 1;
  21. }
  1. p -> next = s;
  2. 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;
}
时间: 2024-11-08 05:52:45

链表学习的相关文章

LIST_ENTRY链表学习

链表是驱动开发中经常遇到的一个数据结构,主要是双向循环链表:要使用链表,需要用到一个LIST_ENTRY的结构,其定义如下: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; // 指向下一个节点 struct _LIST_ENTRY *Blink; // 指向前一个节点 } LIST_ENTRY, *PLIST_ENTRY; 每个双向链表都是一个以链表头作为链表第一个元素,初次使用时需要进行初始化,主要讲链表头的Flink,Blin

数据结构链表学习

今天初步学习数据结构链表,学习过程中感觉对于指针的理解还差很多,而且对于VS的调试也不会使用,调查问题只能靠一遍一遍的梳理逻辑,效率不是一般的低下..接下来得赶紧学习下VS的使用.. 今天链表只是初步学习,写的例子也比较简单,如下: 定义链表的数据结构,只简单的定义了一个数据和一个指向后继的指针 1 struct List { 2 int num; 3 List *next; 4 }; 接下来就是链表的创建,返回一个指针地址赋给主函数中的头指针,用于之后的增删改查等等 1 List *creat

12-15链表学习

一.动态分配内存realloc void*//返回重新分配的内存空间的首地址 realloc(void*//void*指针指向的内存区域必须是使用malloc分配过的,size_t//现在总共需要多少内存空间); 二.链表:单链表,双链表 结点node Data              Data node->next指针       next指针 在定义结构体时,要明确内存空间. 三.保存一组年龄的数据. #include <stdio.h> #include <stdlib.h

数据结构 链表学习笔记

#include<stdio.h> #include<stdlib.h> #include<string.h> struct stu_node{ char num[15]; int score; struct stu_node *next; }; struct stu_node *stu_create() { struct stu_node *head, *newN, *tail; char num[15]; int score; printf("请输入学生的

线性表之单链表学习小结(初学数据结构必看)

花了好几个小时,详细规划出了整个过程,包括所有基本操作...有什么疑问请下方留言 #include<iostream> using namespace std; #define ElemType char #define ERROR 0 #define OK 1 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkList; void init_linklist(LinkList L)/*对单链表进行初始化*/

C++链表学习笔记

如果要保存一些数据类型相同的变量,比如n个int类型的变量,就可以存放在一个数组中,然后通过下标方便的访问.可是数组的缺点也比较多,第一个就是在声明数组的时候,数组的长度必须是明确的,即便是动态声明一个数组,处理器必须要知道长度才能在内存中找出一段连续的内存来保存你的变量.第二个缺点也就是上一句中说到的,数组在内存中的地址必须是连续的,这样就可以通过数组首地址再根据下标求出偏移量,快速访问数组中的内容.现在计算机内存越来越大,这也算不上什么缺点.第三个缺点,也是非常难以克服的缺点,就是在数组中插

链表学习二:链表反转与查找倒数第K个

1 //单链表反转 2 ListNode* RevertList(ListNode* m_pHead){ 3 ListNode* pCurrent = m_pHead; 4 ListNode* pPrev=NULL; 5 ListNode* pNext =NULL; 6 7 while (pCurrent != NULL) 8 { 9 pNext = pCurrent->m_pNext; 10 pCurrent->m_pNext = pPrev; 11 pPrev = pCurrent; 12

链表学习练习题

题目来源:SWUST OJ 程序设计C 实验六 结构体 题目三 学生结构体链表(0068) Description 用结构体建立学生信息,学生信息包括学号.姓名.成绩,建立一个有 n 名学生的链 表, 并将链表输出. Input 一次输入学生信息包括学号.姓名.0 0 0结束程序 Output 从链表表头到表位依次输出. Sample Output C1001 Li 70 M1002 He 89 E1003 Xie 83 M1004 Wu 92 E1005 Bao 80 Sample Input

链表学习笔记

单向链表 struct ListNode {// 单向链表 int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; 从尾到头打印链表 vector<int> TravelListFromTailToHead(struct ListNode* head) {// [从尾到头打印链表] vector<int> result; if(NULL == head) return result; Li