数据结构之线性表

线性表基本知识点

思维导图
在这里插入图片描述

线性表代码

一、顺序表

1. 顺序表定义

  1. 静态定义

    #define MaxSize 50
    typedef struct{
    	ElemType data[MaxSize];
    	int length;
    }SqList;
    
  2. 动态定义

    #define InitSize 100
    typedef struct{
    	ElemType *data;  //分配数组的指针
    	int length,MaxSize;  //数组的当前个数和最大容量
    }SqList;
    
    //初始动态分配语句
    //1.c
    L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize);
    //2.c++
    L.data = new ElemType[InitSize];
    

2.顺序表基操

  1. 插入

    bool ListInsert(SqList &L, int i, ElemType e){//顺序表L,插入位置i,插入元素e
    	//1.判断插入的位置是否正确  i的位置在1到长度加一(末尾插)之间
    	if(i > L.length+1||i < 1)
    		return flase;
    	//2.判断当前存储空间是否满
    	if(L.length >= MaxSize)
    		return flase;
    	//3.从最后一个元素到插入位置i的元素往后移一位
    	for(int j = L.length;j >= i;j--)
    		L.data[j] = L.data[j-1];
    	//4.将插入元素e放进i的位置
    	L.data[i-1] = e;
    	//5.线性表长度加一
    	L.length++;
    	return true;
    }
    

    插入位置和数组下标要区别开来
    位置是1到数组长度;可以插入的位置为1到数组长度+1,此时的加一为末尾最后一个位置,此位置也可以插入。
    数组下标是0到数组长度-1
    插入位置为i ,这个位置在数组中为:L.data[i-1]

  2. 删除

    bool ListDelete(SqList &L, int i, ElemType &e){ //顺序表L,删除位置i,删除元素e
    	//1.判断删除位置是否合法
    	if(i < 1 || i > L.length)
    		return flase;
    	//2.将删除位置元素存起来
    	e = L.data[i-1];
    	//3.将删除位置后一个元素到最后一个元素往前移一位,直接覆盖前面元素
    	for(int j = i;j < L.length;j++)
    		L.data[j-1]=L.data[j];
    	//4.长度减一
    	L.length--;
    	return true;
    }
    
  3. 按值查找(顺序查找)

    int LocateElem(SqList L,ElemType e){//顺序表L,查找元素e
    	//1.顺序查找,找到返回位序
    	for(int i = 0;i < L.length;i++){
    		if(L.data[i]==e)
    			return i+1
    	}
    	//2.未找到,查找失败
    	return 0;
    }
    

二、单链表

1. 单链表定义

typedef struct LNode{
	ElemType data;//数据域
	struct LNode *next;//指针域
}LNode, *LinkList

2.单链表基操

  1. 头插法建立表
    生成链表中结点的次序与输入数据的顺序相反

    LinkList CreateListHead(LinkList &L){//单链表L
    	//从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素
    	LNode *s;
    	int x;//表内元素类型
    	//1.创建头结点
    	L=(LinkList)malloc(sizeof(LNode));
    	//2.初始化为空链表
    	L->next = NULL;
    	//3.循环输入
    	while(scanf("%d",&x) != EOF){
    		//4.创建新结点
    		s=(LNode*)malloc(sizeof(LNode));
    		//5.将新结点插入链表中,L为头指针
    		s->data = x;
    		s->next = L->next;
    		L->next = s;
    	}
    	return L;
    }
    
  2. 尾插法建立表

    LinkList CreateListTail(LinkList &L){//单链表L
    	//从表尾到表头正向建立单链表L,每次均在表尾插入元素
    	int x;//表内元素类型
    	//1.创建尾结点
    	L=(LinkList)malloc(sizeof(LNode));
    	//2.将表尾指针指向结点
    	LNode *s,*r = L;
    	//3.循环输入
    	while(scanf("%d",&x) != EOF){
    		//4.创建新结点
    		s=(LNode*)malloc(sizeof(LNode));
    		//5.将新结点插入链表中
    		s->data = x;
    		r->next = s;
    		r = s;//r指向新的表尾结点
    	}
    	//6.尾结点指针置空
    	r->next = NULL;
    	return L;
    }
    
  3. 按序号查找结点值

    LNode *GetElem(LinkList L,int i){
    //取出单链表L(带头结点)中第i个位置的结点指针
    	int j = 1;
    	//1.头结点赋值给p
    	LNode *p = L->next;
    	//2.i为0,返回头结点
    	if(i==0)
    		return L;
    	//3.i位置不合法,返回空
    	if(i<1)
    		return NULL;
    	//4.从第一个结点开始遍历,一直找到第i个结点
    	while(p&&j<i){
    		p = p->next;
    		j++;
    	}
    	//5.返回第i个结点的指针;如果i大于表长 p=null 直接返回p即可
    	return p;
    	
    }
    
  4. 按值查找表结点

    LNode *LocateElem(LinkList L,ElemType e){
    //取出单链表L(带头结点)中数据域等于e的结点指针,否则返回NULL
    	//1.头结点赋值给p
    	LNode *p = L->next;
    	//2.从第一个结点开始查找数据域等于e的结点
    	while(p!=NULL&&p->next!=e){
    		p = p->next;
    	}
    	//5.找到返回改指针结点,否则返回NULL
    	return p;
    	
    }
    
  5. 插入结点(两种)

    //一、前插
    //1.查找插入结点的前驱位置
    p = GetElem(L,i-1);
    //2.在节点p后插入结点s
    s->next = p->next;
    p->next = s;
    
    //二、后插(在单链表插入中通常采用后插操作,前插均可转换成后插--前插操作之后交换数据域)
    //1.在节点p后插入结点s
    s->next = p->next;//修改指针域
    p->next = s;
    //2.交换数据域
    temp = p->data;
    p->data = s->data;
    s->data = temp;
    
  6. 删除结点

//删除给定结点后一结点*q
	//1.查找删除结点的前驱位置
	p = GetElem(L,i-1);
	//2.令q指向被删除结点
	q = p->next;
	//3.将*q结点从链中断开
	p->next = q->next;
	//4.释放q结点
	free(q);

//删除所给结点*p
	//1.令q指向*p的后继结点
	q = p->next;
	//2.和后继结点交换数据域
	p->data = p->next->data;
	//3.将q结点从链中断开
	p->next = q->next;
	//4.释放q结点
	free(q);
	

三、双链表

1. 双链表节点定义

typedef struct DNode{
	ElemType data;//数据域
	struct DNode *prior,*next;//前驱和后继指针
}DNode,*DLinkList;

2.双链表基操

  1. 插入

    //将*s结点插入到*p之后
    s->next = p->next;
    p->next->prior = s;
    s->prior = p;
    p->next = s;//1.2步必须在4步之前,否则*p后继结点的指针会丢掉
    
  2. 删除

    //删除*p的后继结点*q
    p->next = q->next;
    q->next->prior = p;
    free(q);
    

四、静态链表

静态链表结构类型描述

#define MaxSize 50//静态链表的最大长度
typedef struct{
	ElemType data;//存储数据元素
	int next;//下一个元素的数组下标
}SLinkList[MaxSize];

静态表的插入删除操作与动态链表相同,只需要修改指针,不需要移动元素

合集:
数据结构之线性表
数据结构之栈与队列
数据结构之串
数据结构之树与二叉树
数据结构之图
数据结构之查找
数据结构之排序

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值