【动手学数据结构】第二章 线性表代码

代码使用C++实现,编译器Dev C++ 5.4.0

目录

顺序存储

顺序表

静态顺序表

动态顺序表

链式存储

单链表

带头结点单链表

不带头结点单链表


顺序存储

顺序表

静态顺序表

#include <stdio.h>
#define MaxSize 10

typedef struct{
	int data[MaxSize];		//定义数组 
	int length;				//当前长度 
}SeqList;

//初始化顺序表 
void InitList(SeqList &L){
	for(int i = 0; i < MaxSize; i++){
		L.data[i] = 0;	
	}
	L.length = 0;
}

//插入数据 
//i为位序   e为插入元素 
bool ListInsert(SeqList &L, int i, int e){
	//判断位置是否合法
	if(i<1 || i>L.length+1){
		return false;
	}
	//判断是否已满
	if(L.length >= MaxSize){
		return false;
	} 
	//后移元素 
	for(int j = L.length; j >= i; j--){
		L.data[j] = L.data[j-1];
	}
	L.data[i-1] = e;
	L.length++;
	return true;
}

//删除元素
bool ListDelete(SeqList &L, int i, int &e){
	//判断位置是否合法
	if(i<1 || i>L.length){
		return false;
	}
	e = L.data[i-1];		//得到删除元素
	//前移元素 
	for(int j = i; j < L.length; j++){
		L.data[j-1] = L.data[j];
	}
	L.length--;
	return true;
} 

//按位查找
//i为位序 
int GetElem(SeqList L, int i){
	return L.data[i-1];
} 

//按值查找
//返回位序! 
int LocateElem(SeqList L, int e){
	for(int j = 0; j < L.length; j++){
		if(L.data[j] == e){
			return j+1;
		}
	}
	return 0;
} 


int main(){
	SeqList L;
	InitList(L);
	ListInsert(L,1,1);
	ListInsert(L,2,2);
	ListInsert(L,3,3);
	ListInsert(L,4,4);
	ListInsert(L,5,5);
	
	int position = 3;	//删除元素的位序 
	int e = -1;			//用于把元素带回来 
	ListDelete(L,position,e);
	printf("删除了%d\n",e);
	
	for(int i = 0; i < L.length; i++){
		printf("data[%d]=%d\n",i,L.data[i]);
	}
	
	printf("值为2的元素位序为%d\n",LocateElem(L,2));
	return 0;
}

动态顺序表

#include <stdlib.h> //用于使用malloc和free 
#include <stdio.h> 
#define InitSize 10 //默认初始最大长度
typedef struct{
	int *data;		//动态分配数组的指针 
	int MaxSize;	//最大长度 
	int length;		//当前长度 
}SeqList;

//初始化顺序表 
void InitList(SeqList &L){
	L.data = (int*)malloc(sizeof(int)*InitSize);
	for(int i = 0; i < InitSize; i++){
		L.data[i] = 0;
	}
	L.MaxSize = InitSize;
	L.length = 0;
}

//拓展长度 
void IncreaseSize(SeqList &L, int len){
	int *p = L.data;
	L.data = (int*)malloc(sizeof(int)*(L.MaxSize+len));
	for(int i = 0; i < L.length; i++){
		L.data[i] = p[i];
	}
	L.MaxSize = L.MaxSize + len;
	free(p);
}

//按位查找
int GetElem(SeqList L, int i){
	return L.data[i-1];
} 

int main(){
	SeqList L;
	InitList(L);
	
	for(int i = 0; i < 5; i++){
		L.data[i] = i+1;
		L.length++;
	}
	
	for(int i = 0; i < L.length; i++){
		printf("before:data[%d] = %d\n",i,L.data[i]);
	}
	
	IncreaseSize(L,10);
	
	for(int i = 0; i < 10; i++){
		L.data[i] = i+1;
		L.length++;
	}
	
	for(int i = 0; i < L.length; i++){
		printf("after:data[%d] = %d\n",i,L.data[i]);
	}
	
	printf("%d",GetElem(L,4));
}

链式存储

单链表

带头结点单链表

#include <stdio.h>
#include <stdlib.h>

//带头结点的单链表 

typedef struct LNode{
	int data;			//该节点数据 
	struct LNode *next;	//指向下一个节点的指针 
}LNode, *LinkList;	

//初始化一个空的单链表
bool InitList(LinkList &L){
	L = (LNode*)malloc(sizeof(LNode));
	if(L == NULL){		//内存不足,分配失败 
		return false;
	}
	L->next = NULL;		//头结点后暂无结点 
	return true;
}	

//判断链表是否为空
bool Empty(LinkList L){
	if(L->next == NULL){
		return true;
	}
	return false;
} 

//按位序插入
bool ListInsert(LinkList &L, int i, int e){
	//输入位序不合法 
	if(i<1){
		return false;
	}
	LNode *p;		//指针p指向当前扫描到的节点
	int j = 0;		//当前p指向的是第几个节点
	p = L;			//p指向头结点,头结点为第0个结点
	while(j<i-1 && p!=NULL){	//循环找到第i-1个结点 
		p = p->next;
		j++;
	}
	if(p==NULL){	//i不合法 
		return false;
	} 
	LNode *s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
} 

//后插操作:在p结点后插入元素e
bool InsertNextNode(LNode *p, int e) {
	if(p == NULL){
		return false;
	}
	LNode *s = (LNode*)malloc(sizeof(LNode));
	if(s == NULL){		//内存分配失败 
		return false;
	}
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

//按位序删除
bool ListDelete(LinkList &L, int i, int &e){
	//输入位序不合法 
	if(i<1){
		return false;
	}
	LNode *p;		//指针p指向当前扫描到的节点
	int j = 0;		//当前p指向的是第几个节点
	p = L;			//p指向头结点,头结点为第0个结点
	while(j<i-1 && p!=NULL){	//循环找到第i-1个结点 
		p = p->next;
		j++;
	}
	if(p==NULL){	//i不合法 
		return false;
	} 
	LNode *q = p->next;		//q指向被删除结点 
	e = q->data;			//e返回删除的值 
	p->next = q->next;		//断开删除结点 
	free(q);				//释放删除结点空间 
	return true;
}

//按位查找
LNode* GetElem(LinkList L, int i){
	if(i < 1){
		return NULL;
	}
	LNode *p = L;	//当前结点 
	int j = 0;		//当前结点位序 
	
	while(j<i && p!=NULL){	//循环找到第i个结点 
		p = p->next;
		j++;
	}
	return p;		//没找到返回NULL,找到返回地址 
}

//按值查找
LNode* LocateElem(LinkList L, int e){
	LNode *p = L->next;
	while(p->data!=e && p!=NULL){
		p = p->next;
	}
	return p;
}

//求单链表长度
int Length(LinkList L){
	if(L == NULL || L->next == NULL){
		return 0;
	}
	int len = 0;
	LNode *p = L->next;	//第一个结点 
	while(p!=NULL){
		len++;
		p = p->next;
	}
	return len;
}

//打印所有链表内结点数据 
void PrintList(LinkList L){
	//链表没头结点或链表头结点后无结点退出 
	if(L == NULL || L->next == NULL){
		return;
	}
	int i = 1;			//指向第一个结点 
	LNode *p = L->next;	//第一个结点 
	while(p!=NULL){
		printf("第%d个结点内数据为%d\n",i,p->data);
		p = p->next;
		i++;
	}
}

//尾插法建立单链表
//时间复杂度O(n) 
LinkList List_TailInsert(LinkList &L){
	int x;				//设ElemType为整型
	L = (LinkList)malloc(sizeof(LNode));//建立头结点
	LNode *s,*r = L;	//s为新结点指针,r为表尾指针
	scanf("%d",&x);		//输入结点的值
	while(x!=9999){		//输入9999结束
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;	//为新结点写入数据 
		r->next = s;	//把新结点连接在表尾
		r = s;			//表尾指针指向表尾 
		scanf("%d",&x);
	} 
	r->next = NULL;		//尾结点指针置空
	return L; 
}

//头插法建立单链表 
LinkList List_HeadInsert(LinkList &L){
	int x;
	L = (LinkList)malloc(sizeof(LNode));//建立头结点 
	L->next = NULL;			//需要设为NULL否则PrintList有问题 
	LNode *s = L; 
	scanf("%d",&x);
	while(x!=9999){	
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;		
		s->next = L->next;	//新结点指针指向头结点后一结点 
		L->next = s;		//将新结点放入头结点后 
		scanf("%d",&x);
	}
	return L; 
}

int main(){
	LinkList L;		//L是地址 
	InitList(L);
	printf("isEmpty?%d\n",Empty(L));
	//List_TailInsert(L);
	List_HeadInsert(L);
	printf("isEmpty?%d\n",Empty(L));
	PrintList(L);
	printf("第三个结点数据为%d\n",GetElem(L,3)->data);
	int e = 0;
	ListDelete(L,5,e);
	printf("删除的数据为%d\n",e);
	printf("链表长度为%d\n",Length(L));
	PrintList(L);
}

不带头结点单链表

#include <stdio.h>
#include <stdlib.h>

//不带头结点的单链表 

typedef struct LNode{
	int data;			//该节点数据 
	struct LNode *next;	//指向下一个节点的指针 
}LNode, *LinkList;	

//初始化一个空的单链表
bool InitList(LinkList &L){
	L = NULL;
	return true;
}	

//判断链表是否为空
bool Empty(LinkList L){
	if(L == NULL){
		return true;
	}
	return false;
} 

//不带头节点插入元素 
bool ListInsert(LinkList &L, int i, int e){
	if(i<1){
		return false;
	}
	//插入第一个结点需要特殊处理 
	if(i==1){
		LNode *s = (LNode*)malloc(sizeof(LNode));
		s->data = e;
		s->next = L;
		L = s;		//头指针指向新结点 
		return true; 
	}
	LNode *p;		//指针p指向当前扫描到的节点
	int j = 1;		//当前p指向的是第几个节点
	p = L;			//p指向第一个结点
	while(j<i-1 && p!=NULL){	//循环找到第i-1个结点 
		p = p->next;
		j++;
	}
	if(p==NULL){	//i不合法 
		return false;
	} 
	LNode *s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

int main(){
	LinkList L;
	InitList(L);
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值