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

稍微注意一下两点:

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. android学习笔记15——Galley

    Gallery==>画廊视图 Gallery和Spinnery父类相同——AbsSpinner,表明Garrey和Spinner都是一个列表框. 两者之间的区别是:Spinner显示的是一个垂直 ...

  2. 黄聪:wordpress如何使用wp_rewrite实现自定义伪静态,非301重定向。

    今天,想通过wordpress实现 http://hcsem.com/a?h-1 伪静态为 http://hcsem.com/a-1.html 找了很多资料,终于搞定. 只需要在functions.p ...

  3. PHP转换UTF-8和GB2312的URL编码(转)

    目前WEB的应用中, UTF-8编码和GB2312编码是并存在的,例如百度(baidu.com)和谷歌(google.com)的URL编码分别是GB2312编码和UTF-8编码.由于编码并存引起的乱码 ...

  4. unity客户端与c++服务器之间的简单通讯_1

    // 服务器 # pragma once using namespace std; # include <iostream> # include <string> # incl ...

  5. RMAN_Oracle RMAN的常用Command命令

    2014-12-11 Created By BaoXinjian

  6. Codeforces Round #373 (Div. 2)A B

    Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 这回做的好差啊,a想不到被hack的数据,b又没有想到正确的思维 = = [题目链 ...

  7. 区分listview的item和Button的点击事件

    这两天修改领导通的ListView widget,在ListView中加入Button这类的有 “点击” 事件的widget,发现原来listview的itemclick居然失效了, 后来在网上查资料 ...

  8. 使用SVN进行项目版本管理

    1.摘要 本文描述了利用SVN进行项目版本管理的方法,涉及项目版本号命名规则.SVN目录结构.第三方代码库的管理.版本创建.发布.修订.合并等行为的方法和原则. 2.版本号命名规则 版本号采用主版本号 ...

  9. Java多线程之银行出纳员仿真

    package concurrent; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Qu ...

  10. 程序员遇到Bug时的30个反应

    开发应用程序是一个非常有压力的工作.没有人是完美的,因此在这个行业中,代码中出现bug是相当普遍的现象.面对bug,一些程序员会生气,会沮丧,会心烦意乱,甚至会灰心丧气,而另一些程序员会依然保持冷静沉 ...