线性表的链式存储结构-单链表
2016-08-20 23:38
309 查看
1.预备的基本知识点:
typedef struct Node{ int elem; struct node * next; }node,*LinkList;
对于LinkList L: L是指向定义的node结构体的指针,可以用->运算符来访问结构体成员,即L->elem,而(*L)就是个Node型的结构体了,可以用点运算符访问该结构体成员,即(*L).elem;
对于LinkList *L:L是指向定义的Node结构体指针的指针,所以(*L)是指向Node结构体的指针,可以用->运算符来访问结构体成员,即(*L)->elem,当然,(**L)就是Node型结构体了,所以可以用点运算符来访问结构体成员,即(**L).elem;
在链表操作中,我们常常要用链表变量作物函数的参数,这时,用LinkList L还是LinkList *L就很值得考虑深究了,一个用不好,函数就会出现逻辑错误,其准则是:
如果函数会改变指针L的值,而你希望函数结束调用后保存L的值,那你就要用LinkList *L,这样,向函数传递的就是指针的地址,结束调用后,自然就可以去改变指针的值;
而如果函数只会修改指针所指向的内容,而不会更改指针的值,那么用LinkList L就行了;
2.带头结点的单链表代码实现
#include <stdio.h>#include<stdlib.h>
#include<time.h>
#define MAXSIZE 20
typedef int ElemType;
typedef int Status; // Status值是函数结果状态代码
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
/**
* 单链表整表创建的算法思路: (困扰了很久,一直在头指针和头结点没想通 其实初始化的时候是没有头指针初始化,头指针理解为头结点的地址或者第一个结点的地址)
* 1.声明一指针p和计数器变量i
* 2.初始化一空链表L,让L的头结点的指针指向NULL,即建立一个带头结点的单链表
* 3.循环: 1.生成一个新结点复制给p 2.随机生成一数字赋值给p的数据域 3.将p插入到头结点与新结点之间
*/
void CreateListHead(LinkList *L, int n)
{
LinkList p;
int i;
srand(time(0)); // 初始化随机种子,以便让下面的rand()函数每次都不一样(根据time)
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL; // 先建立一个带头结点的单链表
for(i=0;i<n;i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100+1;
p->next = (*L)->next;
(*L)->next = p;
}
}
void CreateListTail(LinkList *L, int n)
{
LinkList p,r;
int i;
srand(time(0)); // 初始化随机种子,以便让下面的rand()函数每次都不一样(根据time)
*L = (LinkList)malloc(sizeof(Node)); // 为整个线性表
r = *L;
for(i=0; i<n;i++)
{
p = (Node *)malloc(sizeof(Node));
p->data = rand()%100+1;
r->next = p;
r = p;
}
r->next = NULL;
}
/**
* 整个链表的删除
* 1.声明节点p和q
* 2.将第一个结点赋值给p
* 3.循环: 1将下一个结点赋值给q 2.释放p 3.将q赋值给p
*/
Status ClearList(LinkList *L)
{
LinkList p,q;
p = (*L)->next; // p指向第一个结点
while(p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}
/**
* 单链表的读取
* 声明一个指针p指向链表第一个结点,初始化j从1开始
* 当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累积1
* 若到链表末尾p为空,则说明第i个结点不存在,否则查找成功,返回结点p的数据
*/
Status GetElem(LinkList L, int i, ElemType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while(p && j<i)
{
p = p->next;
++j;
}
if(!p || j>i)
{
return ERROR;
}
*e = p->data;
return OK;
}
void main()
{
LinkList *head;//定义指针变量
//int i,x;////定义int变量
//CreateListHead(head, 10);//初始化头指针变量,传的是头指针的地址,为的是能得到函数改变头指针变量的值
//printf("sizeof=%d head=%d\n",sizeof(LinkList),head);//测试结构体的占的内存大小,和头指针的值
//for(i=1;i<=10;i++){//进行循环
// ListInsert(head,i,i);//进行链表的插入
//}
}
相关文章推荐
- 2.3_线性表的链式存储结构_单链表
- 线性表的链式存储结构--链表
- 数据结构之线性表——链表的链式存储(链式描述)
- 数据结构——线性表的伪链表存储(顺序存储链式遍历)
- 结构之美:线性表的链式存储结构——链表
- JAVA数据结构之线性表的链式存储结构——单链表
- 线性表之链式存储结构_单链表相关算法
- 数据结构之线性表——链表的链式存储(链式描述)
- Java基础 - 线性表之链式存储结构-循环链表
- 结构之美:线性表的链式存储结构——链表
- 数据结构一一线性表的链式存储结构之头插法和尾插法建立链表
- 结构之美:线性表的链式存储结构——链表
- 线性表的链式存储结构——单链表
- 03.线性表(二)链式存储结构.单链表1
- 数据结构之线性表-链式存储之静态链表(二)
- 数据结构之线性表——链表的链式存储(链式描述)注释版
- Java基础 - 线性表之链式存储结构-双向链表
- C语言 数据结构 线性表 单链表 线性表的链式存储结构之一
- [SDUT](2117)数据结构实验之链表二:逆序建立链表 ---链式存储(线性表)
- [SDUT](2116)数据结构实验之链表一:顺序建立链表 ---链式存储(线性表)