偶尔看到大一时候写了一个多级链表,听起来好有趣,稍微整理一下。

稍微注意一下两点:

1、指针是一个地址,他自己也是有一个地址。一级指针(带一个*号)表示一级地址,他自身地址为二级地址。二级指针(带两个*号)表示二级地址,他自身地址为三级地址。

那么n级指针表示(带n个*号)表示n级地址,他自身是一个n+1级地址。

    {
int *p1 = new int();
// p1为一级地址
// &p1 自身地址为二级地址。 //类似
int **p2 = &p;
// p2为二级地址
// &p2 自身地址为三级地址。
}

而当我们解引用的时候,顺序则相反。一级指针解引用直接得到指针所指向的值。多级指针解引用,有点不一样,需要看前面有多少个*号。前面*数量直接决定了表示的是多少级指针。多一个*降一级指针,(如果是一级指针,前面的*号就是引用所指向的值)

     {
int *p1 = int new;
int **p2 = &p1;
int ***p3 = &p2; // p3 表示三级地址,相当于&p2
// *p3 表示二级地址,相当于p2
//**p3 表示一级地址, 相当于p1
//***p3表示 **p3指针所引用的值。 相当于*p1;
}

2、而当我们定义一个指针时,只是指定了他自身的地址。他所表示的其他地址是不知道的。所以当我们需要使用一个多级指针的时候,需要确保他引用的那一层的地址是已知道。

     {
int *p1 = new int();
int **p2 = &p1;
int ***p3 = &p2;
int ****p4 = &p3;
}

根据上面的代码,假如我们想要引用****p的值。 他表示的是一级地址的所指向的值(即***p4 == p1),相当于对执行*p1,这时候必须确保***p4的指针是已经知道的,否则引用出错。

多级指针代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
//.....
struct LNode* next;
}LinkList; //to determine whether the list is empty
bool ListEmpty(LinkList***** L)
{
return NULL == ****L;
}
void ListAdress(LinkList***** L)
{
printf("5地址: %d\n",L);
printf("4地址: %d\n",*L);
printf("3地址: %d\n",**L);
printf("2地址: %d\n",***L);
printf("1地址: %d\n",****L);
}
// insert the element in a certain position in list
bool ListInsert(LinkList***** L,ElemType value)
{
//ListAdress(L);
LinkList* insertNode = (LinkList*)malloc(sizeof(LinkList));
insertNode->next=NULL;
insertNode->data=value;
if(ListEmpty(L))
{
(****L)=insertNode;
}
else
{
insertNode->next=(****L);
(****L)=insertNode;
}
}
void ListDisplayValue(LinkList***** L)
{
LinkList* pre = ****L;
while(pre)
{
printf("%d ",pre->data);
pre = pre->next;
}
} int main()
{
LinkList***** L5 = NULL;
L5 = (LinkList*****)malloc(sizeof(LinkList));
(*L5) = (LinkList****)malloc(sizeof(LinkList));
(**L5) = (LinkList***)malloc(sizeof(LinkList));
(***L5) = (LinkList**)malloc(sizeof(LinkList));
//(****L3) = (LinkList*)malloc(sizeof(LinkList));
(****L5) = NULL;
ListAdress(L5);
for(int i = ; i< ;++i)
ListInsert(L5,i+);
ListDisplayValue(L5);
return ;
}

运行结果:(堆分配的内存是递增的)

 5地址:
4地址:
3地址:
2地址:
1地址: Process returned (0x0) execution time : 2.721 s
Press any key to continue.

顺便附上正常链表代码:

 #include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
//.....
struct LNode* next;
}LinkList; //to determine whether the list is empty
bool ListEmpty(const LinkList* L)
{
return NULL == L;
}
//Destroy list
void ListDestroy(LinkList** L)
{
if(ListEmpty((*L)))
return ;
LinkList* pre = *L;
LinkList* p = pre->next;
while(p)
{
free(pre);
pre = p;
p = p->next;
}
free(pre);
(*L) = NULL;
} // the length of list
int ListLength(const LinkList* L)
{
const LinkList* pre = L;
int countNode = ;
while(pre)
{
++countNode;
pre = pre->next;
}
return countNode;
} //display list
void ListDisplay(const LinkList* L)
{
const LinkList* pre = L;
while(pre)
{
printf("%d ",pre->data);
pre = pre->next;
}
}
//get the element that in a certain position pos,
bool GetElement(LinkList* L,int position,ElemType& posElement)
{
LinkList* pre = L;
int index = ;
while(pre&&index<position)
{
++index;
pre = pre->next;
}
if(NULL == pre)
return false;
else
{
posElement = pre->data;
return true;
}
}
//locate the position that indicate the certain element
int LocateElement(LinkList*L,ElemType value)
{
LinkList* pre = L;
int index = ;
while(pre&&pre->data!=value)
{
pre=pre->next;
++index;
}
if(NULL == pre)
return -;
else
return index; }
// insert the element in a certain position in list
bool ListInsert(LinkList** L,int position,ElemType value)
{
if(position <= )
return false;
if(ListEmpty((*L)))
{
if(==position)
{
LinkList* insertNode = (LinkList*)malloc(sizeof(LinkList));
insertNode->next=NULL;
insertNode->data=value;
(*L)=insertNode;
return true;
}
else
return false;
}
LinkList* pre = (*L);
int index = ;
while(pre&&index<position-)
{
pre =pre->next;
++index;
}
if(NULL == pre)
return false;
else
{
LinkList* insertNode = (LinkList*)malloc(sizeof(LinkList));
insertNode->next=NULL;
insertNode->data=value;
insertNode->next = pre->next;
pre->next = insertNode;
return true;
}
} bool ListDelete(LinkList** L,int position,ElemType& deleteValue)
{
if(position <= || ListEmpty((*L)))
return false;
if( == ListLength(*L))
{
if(==position)
{
deleteValue = (*L)->data;
free(*L);
(*L) = NULL;
return true;
}
else
return false;
}
LinkList* pre = (*L);
int index = ;
while(pre&&index<position-)
{
pre =pre->next;
++index;
}
if(NULL == pre)
return false;
else
{
LinkList* DeleteNode = pre->next;
pre->next = DeleteNode->next;
deleteValue = DeleteNode->data;
free(DeleteNode);
return true;
}
}
int main()
{
LinkList* L=NULL;
// DestroyList(&L); // insert
for(int i = ; i!= ; ++i)
{
bool insertOK = ListInsert(&L,ListLength(L)+,i+);
// if(insertOK)
// printf("position: %d ->Element: %d insert success\n",ListLength(L),i+1); //delete element by using the position which was indicated the value of element
}
/*
int deleteValue = 10;// -1 0 5 10 11
int deleteIndex =LocateElement(L,deleteValue);
bool deleteOK = ListDelete(&L,deleteIndex,deleteValue);
if(deleteOK)
printf("position: %d ->Element: %d delete success\n",deleteIndex,deleteValue);
*/ //Get the Element;
for(int i =;i!=;++i)
{
int value = ;
bool ok =GetElement(L,i+,value);
if(ok)
printf("Positoin: %d ->Element: %d\n",i+,value); }
for(int i = ;i!=;++i)
{
int resultIndex =LocateElement(L,i+);
if(-!=resultIndex)
printf("Element: %d ->Position: %d\n",i+,resultIndex);
}
printf("Display all element\n");
ListDisplay(L);
ListDestroy(&L);
ListDisplay(L);
return ;
}

运行结果:

 Positoin:  ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Positoin: ->Element:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Element: ->Position:
Display all element Process returned (0x0) execution time : 0.315 s
Press any key to continue.

以上个人观点,有不妥欢迎指出来。

数据结构-多级指针单链表(C语言)的更多相关文章

  1. js数据结构与算法--单链表的实现与应用思考

    链表是动态的数据结构,它的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 现实中,有一些链表的例子. 第一个就是寻宝的游戏.你有一条线索,这条线索是指向寻找下一条线 ...

  2. 单链表 C语言 学习记录

    概念 链接方式存储 链接方式存储的线性表简称为链表(Linked List). 链表的具体存储表示为: 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的). 链表中 ...

  3. 数据结构——Java实现单链表

    一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...

  4. 不带头结点的单链表------C语言实现

    File name:no_head_link.c Author:SimonKly Version:0.1 Date: 2017.5.20 Description:不带头节点的单链表 Funcion L ...

  5. C++ 数据结构学习二(单链表)

    模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespa ...

  6. PHP数据结构之实现单链表

    学习PHP中,学习完语法,开始尝试实现数据结构,今天实现单链表 <?php class node //节点的数据结构 { public $id; public $name; public $ne ...

  7. 带头节点的单链表-------C语言实现

    /***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...

  8. 数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)

    单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果) 时间限制: 1S类别: DS:线性表->线性表应用 题目描述: 输入范例: -5345646757684654765867 ...

  9. 带头结点的循环单链表----------C语言

    /***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...

随机推荐

  1. NoSQL 35 个非主流数据库

    几乎每个Web开发人员都有自己喜欢的数据库,或自己最熟悉的数据库,但最常见的无外乎以下几种: MySQL PostgreSQL MSSQL SQLite MS Access 或是更简单的XML,文本文 ...

  2. bzoj4716 假摔

    Description [题目背景] 小Q最近喜欢上了一款游戏,名为<舰队connection>,在游戏中,小Q指挥强大的舰队南征北战,从而成为了一名 dalao.在游戏关卡的攻略中,可能 ...

  3. CentOS下用pyenv 和 virtualenv 搭建单机多版本python 虚拟开发环境

    安装 系统环境:CentOS 6.5 安装依赖 yum -y install gcc gcc-c++ make git patch openssl-devel zlib-devel readline- ...

  4. 使用mongo-java-driver3.0.2.jar和mongodb3.0在java代码中的用户验证4

    以下是使用mongo-java-driver3.0.2.jar和mongodb3.0.4在java代码中的用户验证: ServerAddress sa = new ServerAddress(host ...

  5. javaweb工程,Servlet里面获取当前WEB跟路径的文件绝对路径地址

    String base_Url = request.getSession().getServletContext().getRealPath("/"); String window ...

  6. Web上传文件

      客户端      相对于FTP文件上传,Web文件上传速度慢一些,但使用方便,不需要客户端,而且权限比FTP容易控制. Web文件上传采用POST方式,上传文件需要设置FORM的entype属性为 ...

  7. 学习ios键盘和textfield之间操作体会

    所需要计算就是,键盘移动以后是否遮挡住了textfield,需要用到的计算公式: int offset = 键盘的高度-(self.frame.size.height - self.textfiled ...

  8. MongoDB项目中常用方法

    使用MongoDB连接池MongoOptions来进行连接 以及相关方法的调用 //获得驱动地址(这里的驱动 写入了配置文件中) String serverAddressStr = Configure ...

  9. DBA_Oracle Erp R12中文补丁安装升级(案例)

    2014-07-11 Created By BaoXinjian

  10. POJ 3984 迷宫问题(BFS)

    迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, ...