数据结构-多级指针单链表(C语言)
偶尔看到大一时候写了一个多级链表,听起来好有趣,稍微整理一下。
稍微注意一下两点:
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语言)的更多相关文章
- js数据结构与算法--单链表的实现与应用思考
链表是动态的数据结构,它的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 现实中,有一些链表的例子. 第一个就是寻宝的游戏.你有一条线索,这条线索是指向寻找下一条线 ...
- 单链表 C语言 学习记录
概念 链接方式存储 链接方式存储的线性表简称为链表(Linked List). 链表的具体存储表示为: 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的). 链表中 ...
- 数据结构——Java实现单链表
一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...
- 不带头结点的单链表------C语言实现
File name:no_head_link.c Author:SimonKly Version:0.1 Date: 2017.5.20 Description:不带头节点的单链表 Funcion L ...
- C++ 数据结构学习二(单链表)
模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespa ...
- PHP数据结构之实现单链表
学习PHP中,学习完语法,开始尝试实现数据结构,今天实现单链表 <?php class node //节点的数据结构 { public $id; public $name; public $ne ...
- 带头节点的单链表-------C语言实现
/***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...
- 数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)
单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果) 时间限制: 1S类别: DS:线性表->线性表应用 题目描述: 输入范例: -5345646757684654765867 ...
- 带头结点的循环单链表----------C语言
/***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...
随机推荐
- php访问mysql工具类
本文转载自:http://www.cnblogs.com/lida/archive/2011/02/18/1958211.html <?php class mysql { private $db ...
- [Perl] Getopt 函数来接收用户参数的使用
我们在linux常常用到一个程序需要加入参数,现在了解一下perl中的有关控制参数的函数.getopt.在linux有的参数有二种形式.一种是–help,另一种是-h.也就是-和–的分别.–表示完整参 ...
- angularjs中$http、$location、$watch及双向数据绑定学习实现简单登陆验证
使用$http.$location.$watch及双向数据绑定等实现简单的用户登陆验证,记录备忘: 1.$http模拟从后台获取json格式的数据: 2.$watch实时监控数据变化: 3.$loca ...
- 黄聪:wordpress/wp-includes目录文件
wp-includes/cache.php wp-includes/capabilities.php wp-includes/class-IXR.php:Incutio XML-RPC库.包括了 XM ...
- TCP非阻塞通信
一.SelectableChannel SelectableChannel支持阻塞和非阻塞模式的channel 非阻塞模式下的SelectableChannel,读写不会阻塞 SelectableCh ...
- 【Android】源码external/目录中在编译过程中生成的文件列表
=> external/eyes-free: accessibilityvalidator.jar (host,share) => external/mesa3d: libMesa ...
- Carath\'eodory 不等式
(Carath\'eodory 不等式) 利用 Scharwz 引理及线性变换, 证明: 若函数 $f(z)$ 在圆 $|z|<R$ 内全纯, 在 $|z|\leq R$ 上连续, $M(r)$ ...
- Log4j乱码
在log4j.properties里添加encoding , 例如 : log4j.appender.fuscent=org.apache.log4j.DailyRollingFileAppender ...
- Eclipse控制台输出信息的控制
当你在Eclipse中 running/debugging一个应用程序的时候,有关该应用程序的运行调试信息及日志信息都会输出到控制台(console )显示,但是Eclipse只会显示最后一部分的日志 ...
- Windows 64位下安装Redis详细教程
方法/步骤 在D盘新建文件夹[redis],右键解压Redis ZIP包,把所有文件解压到redis文件夹中.(其他盘符也可以滴^_^) 文件介绍: redis-benchmark.exe ...