线性表
线性表就是存储位置时连续的,看下图。 |
1.1基本的操作InitList(*L) 初始化操作,建立一个空的线性表L。 ListEmpty(L) 判断线性表是否为空表,若线性表为空,返回true,否则返回false。 ClearList(*L) 将线性表清空。 GetElem(L,i,*e) 将线性表L中的第i个位置元素值返回给e。 LocateElem(L,e) 在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。 ListInsert(*L,i,e) 在线性表L中第i个位置插入新元素e。 ListDelete(*L,i,*e) 删除线性表L中第i个位置元素,并用e返回其值。 ListLength(L) 返回线性表L的元素个数。 |
1.2基本概念线性表(List):由零个或多个数据元素组成的有限序列。
注意: 1.线性表是一个序列。 2.0个元素构成的线性表是空表。 3.线性表中的第一个元素无前驱,最后一个元素无后继,其他元素有且只有一个前驱和后继。 4.线性表是有长度的,其长度就是元素个数,且线性表的元素个数是有限的,也就是说,线性表的长度是有限的。 若将线性表记为(a1,…,ai-1,ai,ai+1,…an),则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。 |
1.3 线性表的顺序存储
/*
*数据结构线性表 List 数组
*序列Sequence Sq
*/
#include <stdio.h>
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE]; //顺序表中的元素
int length; //顺序表的长度
}SqList; //声明顺序表的类型
//初始化顺序表
void InitList(SqList *L)
{
}
//用e返回L中第i个数据元素的值
int GetElem(SqList L, int i, ElemType *e)
{
if (L.length == 0 || i < 1 || i > L.length) //位置i不能小于1 ,也不能大于数据的最大长度,
return 0; //也不能数据的长度为空
*e = L.data[i - 1];
return 1;
}
//按元素查找
int LocateElem(SqList L, ElemType e)
{
int i = 0;
while (i < L.length && L.data[i] != e) //遍历整个数组,从0开始
i++;
if (i > L.length) return 0;
else return i + 1; //返回的是第几个位置
}
//插入数据元素
//在第i之前插入一个新数据
int ListInsert(SqList *L, int i, ElemType e)
{
int k = 0;
if (L->length == MAXSIZE) //先判断有没有超过最大的存储容量,已经满了
return 0;
if (i < 1 || i > L->length + 1 ) //再判断位置是否过大,或者不存在
return 0;
if (i < L->length) //若插入数据位置不在表尾
{
/*将要插入位置后数据元素向后移动一位*/
for (k = L->length; k >= i; k--)
L->data[k] = L->data[k - 1];
}
L-> data[i - 1] = e; //将新元素插入
L->length++;
return 1;
}
//删除数据元素
int ListDelete(SqList *L , int i , ElemType *e)
{
int k = 0;
if (L->length == 0) //不能为空
return 0;
if (i < 1 || i > L->length) // 删除位置要再范围之内
return 0;
*e = L->data[i - 1];
if (i < L->length)
{
for (k = i; k < L->length; k++)
{
L->data[k-1] = L->data[k];
}
}
L->length--;
return 1;
}
int main()
{
return 0;
}
1.4单链表
/*
* 线性表的实现
* 单链表
*/
#include <stdio.h>
typedef int ElemType;
typedef struct Node
{
ElemType data;
struct Node* next;
}Node , *LinkList;
//单链表初始化,即建立一个空链表
//不带头节点的链表
void InitLink(LinkList L)
{
}
//单链表的初始化
//带头节点的链表
void InitList2(LinkList L){
}
//初始条件,链表已将存在
//获取第i个元素的值,并通过e返回;
int GetElem(LinkList L, int i, ElemType *e)
{
int j;
LinkList p;
p = L->next; //通过头节点获取第一个节点
j = 1; //第几个元素
while (p && j < i) //没有到达指定位置时,接着指向下一个节点
{
p = p->next;
++j; //下标加1
}
if (!p || j > i) //如果 为空,则返回0
{
return 0;
}
*e = p->data;
return 1;
}
// 单链表插入节点
int ListInsert(LinkList *L, int i, ElemType *e)
{
int j = 0;
LinkList p, s;
p = *L;
j = 1;
while (p && j < i) //用于寻找第i-1个节点
{
p = p->next;
j++;
}
if (!p || j > i)
return 0;
s = (LinkList)malloc(sizeof(Node)); //创建一个新的节点
s->data = e; //把数据挂载到节点
s->next = p->next; //实现挂载节点
p->next = s;
return 1; //表示成功;
}
///删除一个已经存在的节点
int ListDelete(LinkList *L, int i, ElemType *e)
{
int j;
LinkList p, q;
p = *L; //承接链表
j = 1; //初始价节点为1
while (p->next && j < i)
{
p = p->next;
++j;
}
if (!(p->next) || j >i)
{
return 0;
}
q = p->next; //q指向要替换的位置
p->next = q->next;
*e = q->data; //把删除的数据传出去
free(q); // 释放要删除的节点
return 1;
}
//将链表清空
int ClearList(LinkList *L)
{
LinkList p, q;
p = (*L)->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return 1;
}
//头插法建立单链表示例
void CreatListHead(LinkList *L, int n)
{
LinkList p;
int i;
*L = (LinkList)malloc(sizeof(Node));//建立一个节点
(*L)->next = NULL; //指向为空
for (i = 0; i < n; i++) // 生成新的节点
{
p = (LinkList)malloc(sizeof(Node));
p->data = 0;
p->next = (*L)->next;
(*L)->next = p;
}
}
//尾插法 建立单链表
void CreatListTail(LinkList *L, int n)
{
LinkList p, r;
int i;
*L = (LinkList)malloc(sizeof(Node));
r = *L;
for (i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node) );
p->data = 0;
r->next = p;
r = p;
}
r->next = NULL;
}