数据结构学习 -- 02

线性表

    1. 线性表是一组有序、有限的数据元素
    2. 除第一个元素外,其它每个元素都仅有一个直接前趋元素
    3. 除最后一个元素外,其它每个元素都仅有一个直接后继元素
    4. 线性表中的数据元素是有序排列的,既 ( a,b ) ≠ ( b, a )
    5. 不论是什么数据类型,所有元素的数据类型都一样
线性表的基本操作
    1. 线性表的声明、创建和初始化
    2. 数据元素的插入、删除、修改
    3. 数据元素的查找、排序
    4. 线性表的释放
    5. 组合、进阶
线性表的具体存储方式
  1. 顺序存储
  2. 链表存储(包括单向链表、双向链表、循环链表)
顺序存储的线性表
  1. 存储地址的计算:
            addr(ai) = addr(a1) + (i – 1) * element_size
            (element_size是一个数据元素所占存储单元的数目)
  2. 声明:
            int a[50], char a[30]
    要素:
            (1).线性表的最大长度 max_size
            (2).正在使用的长度 n
            (3).初始化时,n=0, 增加一个元素:n=n+1;减少一个元素:n=n-1
  3. 操作实现
            3.1插入
                    3.1.1在结尾插入
//伪代码
/*
AppendList (V, n, x)
{
    V[n+1] = x
    n = n + 1
}
*/

//声明、定义
#include "stdio.h"
#define maxsize 10
typedef struct list{
    int array[maxsize];
    int flag;
}list;

//定义插入函数

void Insert(list L, int x){
    L.array[L.flag+1] = x ;
    for(int k=0; k<=L.flag+1; k++){
        printf("%d ",L.array[k]);
    }
}


//定义主函数
int main(){
    list L;
    int x;
    char st;
    int i;
    printf("请输入一组数(用逗号隔开,最大长度为9)\n");
    for(i = 0; st!='\n'; i++){
        scanf("%d", &L.array[i]);
        L.flag = i;
        st = getchar();
    }
    printf("请输入要插入的数\n");
	scanf("%d", &x);
    Insert(L, x);	
}
                    3.1.2在非尾处插入
//伪代码
/*
InsertList(V, n, i, X){
    if(n >= maxsize){
        表满,return
    }
    if(i<1) or (i>n+1) then{
        参数i错误,return
    }
    else {
        for j = n to i step-1
            V[j+1]=V[j]
        end(j)
        V[i] = X
        n = n+1
        return
    }
}
*/
#include "stdio.h"
#define maxsize 10

//初始化
typedef struct list{
    int array[maxsize];
    int flag;
}list;

//定义插入函数
void InsertList(list L, int x, int y){
    int i,j;
    if(y<=0||y>L.flag+1)     //判断插入的位置是否正确,也可以定义一个函数
        printf("插入的位置有误\n");
    else{
    for(i=L.flag;i>y-2;i--){
        L.array[i+1] = L.array[i];
    }
    L.array[y-1]=x;
    L.flag++;
    for(j=0;j<L.flag+1;j++)
		printf("%d ",L.array[j]);
    }
    
}

//定义主函数
int main(){
	list L;
	char st;
	int i;
	int x,y;
	printf("请输入一组数(用逗号隔开)\n");
	for(i=0;st!='\n';i++){
		scanf("%d",&L.array[i]);
		L.flag=i;
		st=getchar();
	}
	printf("请输入要插入的数:\n");
	scanf("%d",&x);
	printf("请输入插入的位置:\n");
	scanf("%d",&y);
	InsertList(L,x,y);	
}
            3.2删除
//伪代码
/*
DeleteList(V, n, i){
    if(i<1)or(i>n) then {
        参数i错误,return
    }
    else{
        for j = i to n-1
            V[j] = V[j+1]
        end(j)
        n = n-1
        return
    }
}
*/
#include "stdio.h"
#define maxsize 10
//初始化
typedef struct list{
    int array[maxsize];
    int flag;
}list;
//定义删除函数
void Delete(list L, int x){
    int i,j;
    if(x<=0||x>L.flag+1)
        printf("删除的位置有误\n");
    else{ 
        for(i=x; i<L.flag+1; i++){
        L.array[i-1] = L.array[i];
    }
    L.flag--;
    for(j=0; j<L.flag+1; j++){
        printf("%d ",L.array[j]);
    }
    }
}
   
//定义主函数
int main(){
	list L;
	char st;
	int i;
	int x;
	printf("请输入一组数(用逗号隔开)\n");
	for(i=0;st!='\n';i++){
		scanf("%d",&L.array[i]);
		L.flag=i;
		st=getchar();
	}
	printf("请输入要删除第几个数:\n");
	scanf("%d",&x);
	Delete(L,x);	
}
            3.3顺序结构线性表的时间复杂度分析
                3.3.1对于插入操作


                3.3.1对于删除操作
链式储存的线性表
1.顺序储存线性表的缺点
    1.1浪费空间
    1.2插入删除的效率低

2.结构特点
每个元素(节点)由两部分组成:
    -数据域
    -地址域
可以用data(x)表示x指针所指向的结点的数据域内容
可以用next(x)表示x指针所指向的结点的指针域内容
线性链表的存储空间是动态分配的,在需要一个新的数据元素时,分配存储单元给个这新元素,在不再需要某个数据元素时,释放该元素所占用的存储单元

3.操作
    3.1集中式管理的实现


    3.2插入操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a5tioVEz-1624185198508)(2021-04-03-21-24-28.png)]

//链式结构线性表的插入操作
/*伪代码
//把b插入到a的前面
InsertLinkedList(head, a, b){
    GetNode(p)     //获取新节点p
    data(p) = b    //新节点的数据域为b

    if (head = Nil) then {     //如果是空表
        head = p;        //让p节点成为表头
        next(p) = Nil;   //让p的指针域指向空集
        return
    }

    if (data(head)==a){  //如果头节点的数据域就是a
        next(p) = head;  //此时p应该是新的头节点,让p的指针域指向原来的头节点
        head = p;        //p成为新的头节点
    }

    else{                 //先找a的前继节点的指针q
        lookFor(head, a, q)
        next(p)=next(q)
        next(q)=p
    }
   return
}
LookFor(head, a, q){     //q是指向a的前继节点的指针
    q = head;
    while(next(q)!=Nil) and (data(next(q))!=a)do
        q = next(q)
    return
}
*/
#include <stdio.h>
#include <stdlib.h>

//下面的内容有参考《大话数据结构》

//建立单链表储存结构
typedef struct list{
    int data;                     //数据域
    struct list *next;            //指针域
}list;
typedef struct list *LinkList;    //定义一个结构体指针

//获取链表的第i个数据
int GetElem(LinkList L, int i, int *e)
{
    int j;
    LinkList p;   //声明一个p结点
    p = L->next;  //让p指向L的第一个结点,p存储的是第一个结点的地址
    j = 1;
    while (p&&j<i){   //*p不为空,或者j<i
    p = p->next;      //让p指向下一个结点
    ++j;
    }

    if(!p || j>i){
        return 0;
    }
    *e = p->data;
    return 1;
}

//单链表的插入
//标准语句: s->next = p->next; p->next = s;
int ListInsert(LinkList *L,int i,int e)
{ 
	int j;
	LinkList p,s;
	p = *L;   
	j = 1;
	while (p && j < i)     //p不为空且j<i
	{
		p = p->next;
		++j;
	} 
	if (!p || j > i)       //没有第i个元素
		return 0;   
	s = (LinkList)malloc(sizeof(list));  //该语句用于生成一个新的节点
	s->data = e; 

	s->next = p->next;     //标准语法
	p->next = s;      

	return 1;
}

    3.3删除操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W1MCi5vA-1624185198510)(2021-04-07-16-07-34.png)]
(《大话数据结构》)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zSF9ZjSK-1624185198511)(2021-04-07-16-08-53.png)]

#include <stdio.h>
#include <stdlib.h>
//建立单链表储存结构
typedef struct list{
    int data;                     //数据域
    struct list *next;            //指针域
}list;
typedef struct list *LinkList;    //定义一个结构体指针
//单链表的删除函数
int LDelete(LinkList *L, int i, int *e){
    int j;
    LinkList p,q;    //定义p,q两个结构体指针
    p = *L;          
    j = 1;
    while(p->next && j<i){  //寻找要删除的第i个元素:1.p结点的指针域不为空;2.j<i
        p = p->next;
        ++j;
    }
    if (!(p->next) || j>i){
        return 0;
    }

    q = p->next;         //核心的两行代码
    p->next = q->next;

    *e = q->data;
    free(q);    //回收q结点
    return 1;
}

p,q; //定义p,q两个结构体指针
p = *L;
j = 1;
while(p->next && j<i){ //寻找要删除的第i个元素:1.p结点的指针域不为空;2.jnext;
++j;
}
if (!(p->next) || j>i){
return 0;
}

q = p->next;         //核心的两行代码
p->next = q->next;

*e = q->data;
free(q);    //回收q结点
return 1;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值