线性表链式实现
- 用一组任意的存储单元存储线性表的数据元素(这组数据存储单元可以是连续的,也可以不连续)
#include <stdio.h>
#include <stdlib.h>
#define ERROR NULL
typedef struct LNode *PtrToLNode;
struct LNode {
int Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;//后面是别名
typedef PtrToLNode List;
/* 初始化线性表 */
PtrToLNode MakeEmpty( )
{
PtrToLNode L;
L = (List)malloc(sizeof(LNode)); /* 产生头结点,并使L指向此头结点 */
if (!L) /* 存储分配失败 */
return 0;
L->Next = NULL; /* 指针域为空 */
return L;
}
//表的创建(头插法:将新创建的结点添加到链表的第一个数据结点之前,作为链表新的首个数据结点)
void CreateList_L1(List &L, int m[], int n){ //此处&为引用,会改变原来值
List p;
int i = 0;
//逆位序输入n个元素的值,建立带表头结点的单链线性表L
L = (List)malloc(sizeof(LNode));
L->Next = NULL; /*初始化定义头节点,
表示头节点的下一个节点为空,
就是该链表只有一个头节点*/
for (i = 0; i < n; i++) {
p = (List)malloc(sizeof(LNode));
p->Data = m[i]; //首先将插入位置之后的链表链接到新结点p上
//scanf("%d", &p->Data); //输入元素值
//插入到表头
p->Next = L->Next; /* 修改新节点的指针域,使其指向头节点*/
L->Next = p; //修改头结点的指点域,使其指向新节点p
}
}
//表的创建(尾插法:把新来的节点插入到上一个尾部,把最后一个节点的next值赋为空)
void CreateList_L2(List &L, int m[], int n) {
List p,r; //结构体指针
int i = 0;
//逆位序输入n个元素的值,建立带表头结点的单链线性表L
L = (List)malloc(sizeof(LNode));
r = L;//定义一个指针,记录每次插入变换后的最后一个节点的指针域信息
for (i = 0; i < n; i++) {
p = (List)malloc(sizeof(LNode));
p->Data = m[i];
r->Next = p; //将 r(当前还是代表头节点的地址)的下一个节点指向p
r = p; //将原本表示头部节点地址的指针赋值为新插入的节点,表示当前节点
}
r->Next = NULL; /*建立一个带头结点的单链表*/
}
/*求表长*/
int length(List PtrL) {
List p = PtrL; /*p指向表的第一个节点*/
int j = 0;
while (p) {
p = p->Next;
j++; /*当前p指向表的第j个节点*/
}
return j;
}
/* 按值查找 */
int Find(int X, List &L )
{
List p = L->Next; /* p指向L的第1个结点 */
while (p && p->Data != X)
p = p->Next;
if (p)
return p->Data;
else
return ERROR;
}
/* 按序号查找 */
int Find2(int K, List &PtrL) {
List p = PtrL;
int i = 0;
while (p != NULL && i < K) {
p = p->Next;
++i;
}
if (i == K) return p->Data;
/*找到第K个,返回数据*/
else return NULL;
/*否则返回NULL*/
}
/*插入*/
int Insert(List &L, int i,int e ) {
//在含头节点的单链线性表L中第i个位置之前插入元素e
List p = L;
int j = 0;
while (p&&j < i - 1) { //寻找第i-1个结点
p = p->Next; ++j;
}
if (!p || j > 1 - 1) { //i小于1或者大于表长+1
printf("参数i错");
return ERROR;
}
List s = (List)malloc(sizeof(struct LNode)); /*申请、填装,生成新结点*/
s->Data = e;
s->Next = p->Next; //插入L中,新结点插入在第i-1个结点的后面
p->Next = s;
return 0;
}
/* 删除 */
int Delete(List &L, int i)
{
//在含有头结点的单链线性表PtrL中,删除第i个元素
List p = L;
int j = 0;
while (p->Next&&j < i - 1) { //寻找第i-1个结点,并令p指向其前趋
p = p->Next; ++j;
}
if (!p->Next || j > i - 1) { //删除位置不合理
printf("第%d个结点不存在", i - 1);
return ERROR;
}
List q = (List)malloc(sizeof(struct LNode)); /*申请、填装,生成新结点*/
q = p->Next; /*q指向第i个结点*/
p->Next = q->Next;
free(q); /*删除并释放结点*/
return 0;
}
void output(List L) {
List p;
p = L;
printf("此时PtrL线性表元素为\n");
p = L->Next;
while (p) {
printf("%d ", p->Data);
p = p->Next;
}
printf("\n");
}
int main() {
List PtrL;//结构体指针
int p1, p2;
p1 = 0;
p2 = 0;
int i = 0;
int m[100];
for (i = 0; i < 5; i++) {
scanf("%d", &m[i]);
}
CreateList_L2(PtrL,m, 5);
printf("PtrL->Data大小为%d位\n", sizeof(PtrL->Data) / sizeof(int));
printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
output(PtrL);
printf("第1位插入1000\n");
Insert(PtrL,1,1000 );
printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
output(PtrL);
printf("删除第2位\n");
Delete(PtrL,2);//删除第2位
printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
output(PtrL);
printf("查找4的位置\n");
p1= Find(4, PtrL);
printf("4在PtrL第%d位\n", p1);
printf("查找第1位\n");
p2 = Find2(1, PtrL);
printf("第1位在PtrL为%d\n", p2);
return 0;
}
运行
1 2 3 4 5
PtrL->Data大小为1位
PtrL->Data长度共6位(包含\0位)
此时PtrL线性表元素为
1 2 3 4 5
第1位插入1000
PtrL->Data长度共7位(包含\0位)
此时PtrL线性表元素为
1000 1 2 3 4 5
删除第2位
PtrL->Data长度共6位(包含\0位)
此时PtrL线性表元素为
1000 2 3 4 5
查找4的位置
4在PtrL第4位
查找第1位
第1位在PtrL为1000
双向链表插入结点
双向链表删除结点
最后再释放结点
free(p);