一、指针与单链表

    1、定义:通过使用指针将节点(结点)链接起来成为链表

    2、节点(结点):

      1)、数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型;

      2)、指针域:主要用来当前节点(结点)的下一个节点的地址;

      3)、使用命名结构体嵌套定义;

      4)、定义结构体

      5)、定义结构体指针

  定义节点数据的代码如下:

  #define DataType int

  typedef struct _node{
DataType data;
struct _node *next;
} Node;

  其中第3行代码使用宏定义的方式定义数据类型,也可以使用类型定义数据类型:

  typedef  int  DataType;

  typedef struct _node{
DataType data;
struct _node *next;
} Node;

  代码作用是一样一样的。

    3、链表:

      1)、将一系列节点通过特定的方式链接足层的数据结构;

      2)、链表中通常会有一个头节点

      3)、链表中通常会有一个尾节点

      4)、链表中通常会有一个当前节点;

 typedef struct _list{
Node *head;
Node *tail;
Node *current;
} List;

  链表的定义需要Node节点定义的支持,若不单独定义也可以直接使用节点指针即可。

      5)、常见的节点操作;节点操作是根据需要自己把握的事情,通常是完成结构数据的初始化等工作。

      6)、对指针使用sizeof运算获取指针长度

    4、链表中常见操作:

      1)、链表初始化initialList;

      2)、链表的头插法addHead;

      3)、链表的尾插法addTail;

      4)、链表中获取指定数据节点的指针getNode;

      5)、链表中删除节点deleteNode;

      6)、链表中获取表的长度getLength;

      7)、输出链表中的所有数据displayList;

  根据以上数据类型的需要和链表中需要的操作可以抽象出链表的抽象数据类型,使用list.h表示:

  #ifndef list_h
#define list_h
typedef int DataType; typedef struct _node{
DataType data;
struct _node *next;
} Node; typedef struct _list{
Node *head;
Node *tail;
Node *current;
} List; void initList(List *);
void addHead(List *, DataType);
void addTail(List *, DataType);
Node *getNode(List *, DataType);
void deleNode(List *, DataType);
int getLength(List *);
void dispList(List *); #endif

  操作实现的代码如下:

   #include <stdlib.h>
#include <stdio.h> #include "list.h" //链表初始化
void initList(List *list){
list->head = NULL;
list->tail = NULL;
list->current = NULL;
} //链表头插法
void addHead(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node->data = iData;
node->next = NULL; if(list->head == NULL){
list->tail = node;
}else{
node->next = list->head;
}
list->head = node; return;
} //链表尾插法
void addTail(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node->data = iData;
node->next = NULL; if(list->head == NULL){
list->head = node;
}else{
list->tail->next = node;
}
list->tail = node; return; } //链表节点获取
Node *getNode(List *list, DataType iData){
Node *node = (Node *)malloc(sizeof(Node));
node = list->head;
while(node != NULL){
if(node->data == iData){
return node;
}else{
node = node->next;
}
} return NULL;
} //删除链表中的节点
void deleNode(List *list, DataType iData){
if(list->head->data == iData){
list->head = list->head->next;
}
Node *prev = list->head;
Node *node = prev->next;
while(node != NULL){
if(node->data == iData){
prev->next = prev->next->next; return;
}else{
prev = prev->next;
node = node->next;
}
} return;
} //链表长度
int getLength(List *list){
Node *node = list->head;
int i = ;
while(node != NULL){
node = node->next;
i++;
} return i;
} //链表输出
void dispList(List *list){
Node *node = list->head;
int i = ;
while(node != NULL){
printf("the %dth node: %d\n", i + , node->data);
node = node->next;
i++;
}
printf("disp finished!\n"); return;
}

  测试代码如下:

    #include "list.h"
#include <stdlib.h> int main(int argc, char **argv)
{
List *list1 = (List *)malloc(sizeof(List));
printf("the first:\n");
initList(list1);
addHead(list1, );
addHead(list1, );
addHead(list1, );
addHead(list1, );
addHead(list1, );
dispList(list1);
printf("the second:\n");
deleNode(list1, );
dispList(list1);
printf("The length: %d\n", getLength(list1));
Node *node = getNode(list1, );
printf("The getNode result: %d\n", node->data); return ;
}

  测试完成功能正常。

  

40深入理解C指针之---指针与单链表的更多相关文章

  1. 00深入理解C指针之--- 指针之外

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是 ...

  2. 02深入理解C指针之---指针类型和值

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 1.指针的类型: 可以在声明指针时,指定指针的类型,例如: (1)void *x  声 ...

  3. 06深入理解C指针之---指针操作和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为一种特殊类型的变量,必须遵守C语言中变量先声明后使用的原则.本节内容中指针的操 ...

  4. 10深入理解C指针之---指针运算和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...

  5. 理解C语言中指针的声明以及复杂声明的语法

    昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...

  6. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  7. 从四个属性的角度来理解C语言的指针也许会更好理解

    文章会在文末更新! 关于指针是什么,很多教材已经作出了定义,大多数都会定义为"存放变量内存地址的变量".从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了.我个人 ...

  8. 理解git 中的HEAD指针&branch指针

    理解git 中的HEAD指针&branch指针 Yooye关注 2019.02.28 10:44:32字数 492阅读 668 HEAD指针 使用git checkout 来移动HEAD指针, ...

  9. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

随机推荐

  1. debian常用指令

    查看软件xxx安装内容 dpkg -L xxx 查找软件 apt-cache search 正则表达式 查找文件属于哪个包 dpkg -S filename apt-file search filen ...

  2. Java中的==和equals的区别详解

    1.基础知识 (1)String x = "hello"; (2)String x = new String ("hello"); 第1种方式的工作机制是,首先 ...

  3. 【费用流】bzoj1834: [ZJOI2010]network 网络扩容

    还是稍微记一下这个拆点模型吧 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求:  1.在不扩容的情况下,1到N的最大流:  ...

  4. matplotlib绘图股票走势图实践

    导入模块 import pandas as pdimport numpy as npfrom pandas import Series,DataFrameimport matplotlib.pyplo ...

  5. JDBC操作数据库的详细步骤

    1.注册驱动 告知JVM使用的是哪一个数据库的驱动 2.创建连接 使用JDBC中的类,完成对MySQL数据库的连接 3. 得到执行sql语句的Statement对象 通过连接对象获取对SQL语句的执行 ...

  6. 标准C++(2)

    一.类 C++是一种面向对象的语言,它在C语言的基础上添加了一种新的数据结构,类 ——class class是一种复合型的数据结构 它能够由不同类型的变量及函数组成 C++中的class与struct ...

  7. Linux菜鸟起飞之路【十】进程管理

    一.基本概念 进程:程序的一次动态执行 守护进程:在后台运行并提供系统服务的进程 僵尸进程:完成了生命周期但却依然留在进程表中的进程,我们称之为 “僵尸进程” 父进程:指已创建一个或多个子进程的进程. ...

  8. Python学习笔记:configparser(INI格式配置文件解析)

    在平时的开发中感觉INI格式的配置文件使用还是挺需要的,有时会使用一个单独的py来存放一些常量或者配置项,大多时候这样倒是挺好用的,但是如果某些配置项需要在运行时由用户来修改指定,比如很多app在关闭 ...

  9. 用Python抓取并分析了1982场英雄联盟数据,教你开局前预测游戏对局胜负!

    英雄联盟想必大多数读者不会陌生,这是一款来自拳头,由腾讯代理的大型网络游戏,现在一进网吧,你就能发现一大片玩英雄联盟的人.在2017年中国战队无缘鸟巢的世界总决赛后,一大片人选择了弃游,只是终究没躲过 ...

  10. PAT Basic 1076

    1076 Wifi密码 下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请 ...