您的位置:首页 > 理论基础 > 数据结构算法

线性表的链式存储结构-单链表

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);//进行链表的插入
//}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息