线性表(Linear List)
由同类型数据元素构成的有序序列的线性结构
无头结点的线性链表
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode *PtrToLNode;
struct LNode {
ElemType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
//List Insert(int i, ElemType X, List L);
//根据值查找节点
//X是要查询的值,L是链表的头指针
Position FindData(ElemType X, List L)
{
List p = L;
while(p->Data != X && p)
p = p->Next;
if(p)
return p;
else
return NULL;
}
//根据序号查找
//N是要查询的序号值,L是链表的头指针
Position FindNth(int N, List L)
{
List p = L;
int i = 1;
while(p && i < N)
{
p = p->Next;
i++;
}
if(i == N)
return p;
else
return NULL;
}
//根据序号插入
//在第i个节点插入一个值为X的新节点
//由于该链表没有头结点,当链表为空或在第一个节点前插入新节点,会导致头指针指向改变,所以函数返回类型为List
List Insert(int i, ElemType X, List L)
{
int j = 1;
List s, p = L;
//插入位置在第一个节点前
if(i == 1)
{
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = p;
return s;
}
//该循环结束有三种可能
//1.(p==NULL && j<i-1)
//2.(p!=NULL && j>=i-1)
//3.(p==NULL && j>=i-1)
while(p && j < i-1)
{
p = p->Next;
j++;
}
//对于上面循环结束的三种可能
//1和3不满足插入条件,超过表长
//在(j=i-1&&p!=NULL)时可以满足插入条件,但是j>i-1即插入位置小于1
//若不满足插入条件,直接返回原指针
if(j > i-1 || !p)
return L;
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = p->Next;
p->Next = s;
return L;
}
//根据序号删除节点
List Delete(int i, ElemType *X, List L)
{
List p = L, s;
int j = 1;
if(i == 1)
{
if(p)
{
s = p;
p = s->Next;
*X = s->Data;
free(s);
printf("删除的值是:%d\n", *X);
return p;
}
else
return p;
}
while(p && j<i-1)
{
p = p->Next;
j++;
}
if(!p || j>i-1)
return p;
if(p->Next)
{
s = p->Next;
p->Next = s->Next;
*X = s->Data;
free(s);
printf("删除的值是:%d\n", *X);
return L;
}
else
return L;
}
//销毁线性表
void ClearList(List *L)
{
List p;
while(L)
{
p = (*L)->Next;
free(*L);
*L = p;
}
}
//逐个输出线性表中的元素
void print(List L)
{
List p = L;
while(p)
{
printf("%d ", p->Data);
p = p->Next;
}
printf("\n");
}
有头结点的线性链表
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int ElemType;
typedef struct LNode *List;
struct LNode {
ElemType Data;
List Next;
};
//初始化线性表
void Init(List *L)
{
(*L) = (List)malloc(sizeof(struct LNode));
if(!(*L))
exit(1);
(*L)->Next = NULL;
}
//摧毁线性表
void DestoryList(List *L)
{
List p;
while(*L)
{
p = (*L)->Next;
free(*L);
*L = p;
}
}
//清空线性表
void ClearList(List L)
{
List p = L;
p = L->Next;
DestoryList(&p);
}
//判断线性表是否为空
bool isEmpty(List L)
{
return (L->Next == NULL);
}
//返回线性表元素个数
int Length(List L)
{
int i = 0;
List p = L->Next;
while(p)
{
p = p->Next;
i++;
}
return i;
}
//查询指定位置的元素值
//i为位置的序号,如果查询到将值赋值给X
void GetElem(List L, int i, ElemType *X)
{
int j = 1;
List p = L->Next;
//该循环结束有三种可能
//1.(p == NULL && j < i)
//2.(p != NULL && j >= i)
//3.(p == NULL && j >= i)
while(p && j < i)
{
p = p->Next;
j++;
}
//对于上面3种循环结束条件
//1和3不成立,因为查找的位置已近超出了线性表的长度
//2中的j > i不合法,查询的位置小于线性表的最小有效位置
if(!p || j > i)
exit(1);
*X = p->Data;
}
//查找线性表中是否有数据X
int LocateElem(List L, ElemType X)
{
List p = L->Next;
//该循环结束有2种条件
//1.p == NULL
//2.(p != NULL && p->Data == X)
while(p && p->Data != X)
p = p->Next;
//条件1代表不存在
//条件2代表存在
return p != NULL;
}
//在指定位置插入新节点
//i为新节点的插入位置,X为新节点中的值
void Insert(List L, int i, ElemType X)
{
int j = 0;
List s, p = L;
while(p && j < i-1)
{
p = p->Next;
j++;
}
if(!p || j > i-1)
exit(1);
s = (List)malloc(sizeof(struct LNode));
s->Next = p->Next;
s->Data = X;
p->Next = s;
}
//删除指定的节点
//i为删除的节点的位置,*X保存删除的节点的值
void DeleteList(List L, int i, ElemType *X)
{
int j = 0;
List s, p = L;
while(p->Next && j < i-1)
{
p = p->Next;
j++;
}
if(!p->Next || j > i-1)
exit(1);
s = p->Next;
p->Next = s->Next;
*X = s->Data;
free(s);
}
//输出线性表中的元素
void print(List L)
{
List p = L->Next;
while(p)
{
printf("%d ", p->Data);
p = p->Next;
}
printf("\n");
}