一、指针与单链表

    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. IOS7的变化

    API变化: 1.弃用 MKOverlayView 及其子类,使用类 MKOverlayRenderer: 2.弃用 Audio Toolbox framework 中的 AudioSession A ...

  2. 如何下载并安装 robomongo 到Ubuntu 系统

    官网下载软件,https://robomongo.org/download wget https://download.robomongo.org/1.2.1/linux/robo3t-1.2.1-l ...

  3. CSS(非布局样式)

    CSS(非布局样式) 问题1.CSS样式(选择器)的优先级 1.计算权重 2.!important 3.内联样式比外嵌样式高 4.后写的优先级高 问题2.雪碧图的作用 1.减少 HTTP 请求数,提高 ...

  4. Linux inode 之我见

    Linux硬盘组织方式为:引导区.超级块(superblock),索引结点(inode),数据块(datablock),目录块(diredtory block).其中超级块中包含了关于该硬盘或分区上的 ...

  5. loj2005 「SDOI2017」相关分析

    鬼畜线段树--Orz Capella #include <iostream> #include <cstdio> using namespace std; int n, m, ...

  6. webdriver高级应用- 测试HTML5语言实现的视频播放器

    能够获取HTML5语言实现的视频播放器,视频文件的地址.时长,控制播放器进行播放或暂停播放等操作. #encoding=utf-8 import unittest from selenium impo ...

  7. day04_07 while循环01

    while循环结构: #while 条件: print("any") print("any") 死循环案例 num = 1 while num<=10 : ...

  8. Android library projects cannot be launched解决方法

    着了一个例子项目,总是报标题说的错误. 解决方法如下: 红圈的地方,勾掉. 貌似如果你这个项目是作为一个被引用的project的话, 要勾上这个.单独作为一个app的话,不能勾选这个. --不懂,瞎写 ...

  9. [automator篇][5]Viewer 提示connect to adb fail

    7. UIAutomatorViewer提示: Unable to connect to adb. Check if adb is installed correctly 解决,sdk升级到了25产生 ...

  10. TOJ1698: Balanced Lineup

    Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...