数据结构上机期末考试,线性表两种存储方式对应的增删改查基本操作应该是必考的。
特此记录
1.线性表的顺序存储的基本操作
物理上的先后顺序表示逻辑的先后顺序
1.1数据定义
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define ERROR -1
#define maxsize 100
//数据组织的整体性,将数组和指针last封装成一个结构体lnode
//last是最后一个元素在数组中的位置,表空时就是-1
struct lnode
{
char data[maxsize];
int last;
};
typedef struct * lnode list;
1.2初始化结构体
//初始化结构体
list makeEmpty()
{
list l;
//分配空间
l=(list)malloc(sizeof(struct lnode));
l->last=-1;//置为空
return l;
}
1.3查找元素
//查找元素
int find(list l,char x)
{
int i=0;
while(i<=l->last&&l->data[i]!=x)
i++;
if(i>l->last) return ERROR;
else return i;//返回存储位置
}
1.4插入元素
//插入元素
bool insert(list l,char x,int i)//在第i个位置,也就是数组下标是i-1,插入x
{
if(l->last==maxsize-1){
printf("表空间已满,不能插入");
return false;
}
if(i<1||i>l->last+2){
printf("插入位置不合法,不能插入");
return false;
}
int j;
for(j=l->last;j>=i-1;j--){
l->data[j+1]=l->data[j];//将i-1以及后面的元素向后移动
}
l->data[i-1]=x;
l->last++;
}
1.5删除元素
//删除元素
bool delete(list l,int i)
{
if(i<1||i>l->last+1){
printf("元素不存在");
return false;
}
int j;
for(j=i;j<=l->last;j++){
l->data[j-1]=l->data[j];
}
l->last--;
return true;
}
2.线性表的链式存储的基本操作
2.1结构定义
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
struct lnode
{
char data;
struct lnode * next;
};
typedef lnode * list;
2.2求链表长度
//求表长
int len(list l)
{
list p;
int cnt=0;
p=l;//p指向表的第一个节点
while(p){
p=p->next;
cnt++;
}
return cnt;
}
2.3查
2.3.1查找第k个元素并返回
//查找第K个元素并返回
char findkth(list l,int k)
{
list p=l;
int cnt=0;
while(p&&cnt!=k-1){
p=p->next;
cnt++;
}
if(cnt==k&&p){
return p->data;
}
else{
return ERROR;
}
}
2.3.2查找指定的值返回对应的节点
//根据值查找
list findx(list l,char x)
{
list p=l;
while(p&&p->data!=x){
pp=p->next;
}
if(p&&p->data==x){
return p;
}
else return NULL;
}
2.4插入元素
2.4.1不带头结点的链表的插入操作
//不带头结点的链表的插入
list insert(list l,char x,int i)
{
//1.申请节点并初始化
list pre,tmp;
pre=l;//pre指向第一个节点
tmp=(list)malloc(sizeof(struct lnode));
tmp->next=NULL;
tmp->data=x;
//2.如果插入到第一个元素之前也就是第0个位置 要特殊处理
if(i==1){
tmp->next=l;
return tmp;
}
//3.ok现在开始正式遍历了,我们的目标是查找位序为i-1的节点
int cnt=1;
while(pre&&cot<i-1){
pre=pre->next;//临时指针向后移动
cot++;
}
if(pre==NULL||cnt!=i-1){
printf("插入位置参数有误");
free(tmp);
return NULL;
}
else{//记住这里pre指向的是下标为i-2的位置,也就是i-1的前一个!
tmp->next=pre->next;
pre->next=tmp;
return l;
}
}
2.4.2带头结点的链表的插入操作
//带头结点的链表的插入
bool insert2(list l,char x,int i)
{
//默认l有头节点
list tmp,pre;
tmp=(list)malloc(sizeof(struct lnode));
tmp->data=x;
tmp->next=NULL;
//查找位置为i-1的节点
pre=l;
int cnt=0;
while(pre&&cnt<i-1){
pre=pre->next;
cnt++;
}
if(pre==NULL||cnt!=i-1){
free(tmp);
return false;
}
else{
tmp->next=pre->next;
pre->next=tmp;
return true;
}
}
2.5删除元素
2.5.1带头结点的链表的删除操作
//删除节点(带头结点的)
bool delete(list l,int i)
{
list tmp,pre;
int cnt=0;
pre=l;
while(pre&&cnt<i-1){
pre=pre->next;
cnt++;
}
if(pre==NULL||cnt!=i-1||pre->next==NULL){
printf("参数错误");
return false;
}
else{
tmp=pre->next;
pre->next=tmp->next;
free(tmp);
return true;
}
}
3.总结
总结来讲,带上头结点的链表,增删改还是更加容易一些,代码统一