王道线性表2-05 定义和初始化单链表

代码1-42

单链表的操作:初始化 长度 插入 找元素
单链表链式存储; (顺序表顺序存储)

顺序表有 静态分配动态分配
单链表 动态分配

InitList()
ListEmpty()
ListLength()
GetItem()
ListInsert();
ListTraverse()

总结

1.定义线性表

注意定义

typedef <数据类型> <别名>
typedef int zhengshu;

想要使 struct LNode的别名变成LNode

struct LNode
{
  ElemType data;
  struct LNode *next;
}
typedef struct LNode LNode;
typedef struct LNode *LinkList; //定义指针指向头结点
LNode *L=(LNode)malloc(sizeof(LNode));

定义头指针指向头结点,找到第一个结点,相当于所有结点都能找到
下面是更简洁的方式

typedef struct LNode
{
  ElemType data;
  struct LNode *next;
}LNode,*LinkList;//合起来写,给LNode起个别名叫LinkList

LNode与LinkList强调的不同,
LNode强调返回结点,
LinkList强调单链表,从单链表找到第i个结点 LNode *
下面这样写也对

LNode* GetElem_CL(LNode * L,int i,ElemType *e)
LNode* GetElem_CL(LinkList L,int i,ElemType *e)
{ /* 当第i个元素存在时,其值赋给e并返回L,否则返回p */
  int j=1; /* 初始化,j为计数器 */
  LNode *p=L->next; /* p指向第一个结点 */
  if(i<0||i>ListLength_CL(L)) /* 第i个元素不存在 */
    return NULL;
  if(i==0)
  	return L;
  while(j<i)
  { /* 顺指针向后查找,直到p指向第i个元素 */
    p=p->next;
    j++;
  }
  *e=p->data; /* 取第i个元素 */
  return p;
}

2.初始化一个单链表

2.1不带头结点

判断是否为空—L = NULL

bool InitList(LinkList &L)
{ /* 操作结果:构造一个空的线性表L */
  L=NULL;//空表
  return true;
}
void test(){
	LinkList L;//声明一个指向单链表的指针
	InitList(L);//初始化一个空表
	...
}
2.2带头结点的初始链表
bool InitList(LinkList &L)
{ /* 操作结果:构造一个空的线性表L */
  L=(LNode *)malloc(sizeof(LNode)); /* 在内存中申请一个结点的内存空间,并使指针L指向此头结点 */
  if(L==NULL) /* 存储分配失败 */
    return false;
  L->next=NULL; /* 头结点之后没有结点 */
  return true;
}

判断单链表是否为空
-----L->next == NULL ;即头结点之后还有没有结点

bool Empty(LinkList L){
	if(L->next==NULL)
		return true;
	else
		return false;
}
void test(){
	LinkList L;//声明一个指向单链表的指针
	InitList(L);//初始化一个空表
	...
}

3.代码

最后给出可运行成功的完整代码:

#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0

typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
/* c2-2.h 线性表的单链表存储结构 */
struct LNode
{
  ElemType data;  //数据域
  struct LNode *next; //指针域
};//定义结点

typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */

Status InitList_CL(LinkList *L)
{ /* 操作结果:构造一个空的线性表L */
  *L=(LinkList)malloc(sizeof(struct LNode)); /* 在内存中申请一个结点的内存空间,并使指针L指向此头结点 */
  //struct LNode *L=(struct LNode)malloc(sizeof(struct LNode));//定义指向结点的指针
  if(!*L) /* 存储分配失败 */
    exit(OVERFLOW);
  (*L)->next=*L; /* 指针域指向头结点 */
  return OK;
}
Status ListEmpty_CL(LinkList L)
{ /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  if(L->next==L) /* 空 */
    return TRUE;
  else
    return FALSE;
}
int ListLength_CL(LinkList L)
{ /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  int i=0;
  LinkList p=L->next; /* p指向头结点 */
  while(p!=L) /* 没到表尾 */
  {
    i++;
    p=p->next;
  }
  return i;
}
Status GetElem_CL(LinkList L,int i,ElemType *e)
{ /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
  int j=1; /* 初始化,j为计数器 */
  LinkList p=L->next->next; /* p指向第一个结点 */
  if(i<=0||i>ListLength_CL(L)) /* 第i个元素不存在 */
    return ERROR;
  while(j<i)
  { /* 顺指针向后查找,直到p指向第i个元素 */
    p=p->next;
    j++;
  }
  *e=p->data; /* 取第i个元素 */
  return OK;
}
Status ListInsert_CL(LinkList *L,int i,ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
  LinkList p=(*L)->next,s; /* p指向头结点 */
  int j=0;
  if(i<=0||i>ListLength_CL(*L)+1) /* 无法在第i个元素之前插入 */
    return ERROR;
  while(j<i-1) /* 寻找第i-1个结点 */
  {
    p=p->next;
    j++;
  }
  s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */
  s->data=e; /* 插入L中 */
  s->next=p->next;
  p->next=s;
  if(p==*L) /* 改变尾结点 */
    *L=s;
  return OK;
}
Status ListTraverse_CL(LinkList L,void(*vi)(ElemType))
{ /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
  LinkList p=L->next->next;
  while(p!=L->next)
  {
    vi(p->data);
    p=p->next;
  }
  printf("\n");
  return OK;
}

void visit(ElemType c)
{
  printf("%d ",c);
}

void main()
{
  LinkList L;
  ElemType e;
  int j;
  Status i;
  i=InitList_CL(&L); /* 初始化单循环链表L */
  printf("初始化单循环链表L i=%d (1:初始化成功)\n",i);
  i=ListEmpty_CL(L);
  printf("L是否空 i=%d(1:空 0:否)\n",i);
  ListInsert_CL(&L,1,3); /* 在L中依次插入3,5 */
  ListInsert_CL(&L,2,5);
  i=GetElem_CL(L,1,&e);
  j=ListLength_CL(L);
  printf("L中数据元素个数=%d,第1个元素的值为%d。\n",j,e);
  printf("L中的数据元素依次为:");
  ListTraverse_CL(L,visit);
}

结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值