数据结构&刷题

数据结构 线性表

前天完成了java的每日一题,今天开始直到明年都会学习分享数据结构的有关内容,代码会用C++,可能会用Java代码

了解线性表

首先我们要了解线性表

线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点)
线性表的相邻元素之间存在着序偶关系。如用(a1,…,ai-1,ai,ai+1,…,an)表示一个顺序表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n时,ai有且仅有一个直接前驱

线性表的存储结构

线性表主要由顺序表示或链式表示。在实际应用中,常以栈、队列、字符串等特殊形式使用。
顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,称为线性表的顺序存储结构或顺序映像(sequential mapping)。
它以“物理位置相邻”来表示线性表中数据元素间的逻辑关系,可随机存取表中任一元素。
链式表示指的是用一组任意的存储单元存储线性表中的数据元素,称为线性表的链式存储结构。它的存储单元可以是连续的,也可以是不连续的。在表示数据元素之间的逻辑关系时,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置),这两部分信息组成数据元素的存储映像,称为结点(node)。它包括两个域;存储数据元素信息的域称为数据域;存储直接后继存储位置的域称为指针域。指针域中存储的信息称为指针或链

线性表的基本操作:

接下来以一些题目的方式展示线性表的一些基本操作

  1. 删除顺序表中的所有偶数
    【问题描述】已知顺序表的基本操作,且顺序表中存放了系列整数,请删除其中所有的偶数。
    【输入形式】线性表中元素个数 线性表中的各元素
    【输出形式】将删除偶数后的顺序表中各元素以空格间隔输出
    【样例输入】
    5
    12 23 34 45 56
    【样例输出】
    23 45
    【样例说明】
    第一行为顺序表中元素个数
    第二行为顺序表中的元素的值
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define INIT_LIST_SIZE  10
#define INCREMENT 5
typedef int elemtype;

//1、顺序表的数据类型定义
struct sqList
{
    elemtype *elem;
    int listsize;
    int length;
};

//2、基本操作的实现
//1:初始化
void initList(sqList &L)
{
    //申请空间
    L.elem = (elemtype *) malloc(sizeof(elemtype) * INIT_LIST_SIZE);
    if (L.elem == NULL)
    {
        cout << "空间分配不成功!" << endl;
        exit(0);
    }
    L.listsize = INIT_LIST_SIZE;
    L.length = 0;
}
//2:按值查找
int locate(sqList L, elemtype e)
{
    int index = L.length - 1;
    while (index >= 0)
    {
        if (L.elem[index] == e)
            break;
        index--;
    }
    return index;
}

//3:插入(在第i个位置插入元素e)
void listInsert(sqList &L, int i, elemtype e)
{
    if (i < 1 || i > L.length + 1)
    {
        cout << "插入的位置不合理!" << endl;
        exit(0);
    }
    if (L.length >= L.listsize)
    {
        elemtype *newbase;
        newbase = (elemtype *) realloc(L.elem,sizeof(elemtype) * (L.listsize + INCREMENT));
        if (newbase == NULL)
        {
            cout << "空间增加不成功!" << endl;
            exit(0);
        }
        L.elem = newbase;
        L.listsize += INCREMENT;
    }
    for(int j=L.length-1; j>=i-1; j--)
        L.elem[j+1]=L.elem[j];
    L.elem[i-1]=e;
    L.length++;
}

//4:追加(将元素插入到表尾)
void add(sqList &L, elemtype e)
{
    if (L.length >= L.listsize)
    {
        elemtype *newbase;
        newbase = (elemtype *) realloc(L.elem,sizeof(elemtype) * (L.listsize + INCREMENT));
        if (newbase == NULL)
        {
            cout << "空间增加不成功!" << endl;
            exit(0);
        }
        L.elem = newbase;
        L.listsize += INCREMENT;
    }
    L.elem[L.length] = e;
    L.length++;
}

//5:删除(删除第i个数据元素,将元素的值通过变量e返回)
void listDelete(sqList &L, int i, elemtype &e)
{
    if(i<1||i>L.length)
    {
        cout<<"删除的元素不存在!"<<endl;
        exit(0);
    }
    e=L.elem[i-1];
    for(int j=i; j<=L.length-1; j++)
        L.elem[j-1]=L.elem[j];
    L.length--;
}

//6:遍历
void printList(sqList L)
{
    for (int i = 0; i < L.length; i++)
        cout << L.elem[i] << " ";
    cout << endl;
}

void listDeleteEven(sqList &L)
{
    int i = 0;
    while (i < L.length)
    {
        if (L.elem[i] % 2 == 0)
        {
    
            for (int j = i; j < L.length - 1; j++)
            {
                L.elem[j] = L.elem[j + 1];
            }
         
            L.length--;
        }
        else
        {
            i++;
        }
    }
    
    
}

int main()
{
	sqList L;
	int n;
	cin>>n;
	int e;
	initList(L);
	for(int i=1;i<=n;i++)
        {
		cin>>e;
		add(L,e);
	}
	listDeleteEven(L);
	printList(L);
	return 0;
}

2.有序顺序表的基本操作-插入
【问题描述】设计有序顺序表,内容包括类型定义、有序顺序表的初始化、插入、删除、遍历等操作,请补充完整。
【输入形式】
【输出形式】
【样例输入】
5
12 22 10 32 23
【样例输出】
10 12 22 23 32
【样例说明】
第一行为输入元素个数
第二行为输入元素的值

#define LISTSIZE 10
#define INCREMENT 2
#include <stdlib.h>
#include <iostream>
using namespace std;
struct OSqList
{
	int *elem;
	int listsize;
	int length;
};

void initOSqList(OSqList &L)
{
	L.elem=(int *)malloc(sizeof(int)*LISTSIZE);
	L.listsize=LISTSIZE;
	L.length=0;
}

int getPrior(OSqList L,int e)
{
	int index;
	for(index=0;index<L.length;index++)
        {
		if(L.elem[index]>e)
			break;
	}
	return index;
}
void oSqlistInsert(OSqList &L,int e)
{
	 if (L.length >= L.listsize)
	    {
	        int *newbase;
	        newbase = (int *)realloc(L.elem, sizeof(int) * (L.listsize + INCREMENT));
	        if (newbase == NULL)
	        {
	            exit(0);
	        }
	        L.elem = newbase;
	        L.listsize += INCREMENT;
	    }
	
	    int i = getPrior(L, e);
	
	    for (int j = L.length; j > i; j--)
	    {
	        L.elem[j] = L.elem[j - 1];
	    }
	
	    L.elem[i] = e;
	    L.length++;

}
void printOSqlist(OSqList L)
{
	for(int i=0;i<L.length;i++)
		cout<<L.elem[i]<<" ";
	cout<<endl;
}
int main()
{
	OSqList L;
	int n;
	int e;
	initOSqList(L);
	cin>>n;
	for(int i=1;i<=n;i++)
        {
		cin>>e;
		oSqlistInsert(L, e);
	}
	printOSqlist(L);
	return 0;
}

3.删除顺序表中的重复元素
【问题描述】顺序表中存放着若干整数,升序排列,要求删除其中的重复元素
【输入形式】有序顺序表中存放的元素个数和元素的值
【输出形式】删除重复元素后的有序顺序表
【样例输入】
8
1 1 2 2 3 4 4 5
【样例输出】1 2 3 4 5
【样例说明】
第一行为顺序表中元素个数
第二行为顺序表中存放的元素的值

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define  INIT_LIST_SIZE  10
#define INCREMENT 5
typedef int elemtype;

//1、顺序表的数据类型定义
struct sqList 
{
	elemtype *elem;
	int listsize;
	int length;
};

//2、基本操作的实现
//1:初始化
void initList(sqList &L) 
{
	//申请空间
	L.elem = (elemtype *) malloc(sizeof(elemtype) * INIT_LIST_SIZE);
	if (L.elem == NULL)
        {
		cout << "空间分配不成功!" << endl;
		exit(0);
	}
	L.listsize = INIT_LIST_SIZE;
	L.length = 0;
}
//2:按值查找
int locate(sqList L, elemtype e)
 {
	int index = L.length - 1;
	while (index >= 0) 
        {
		if (L.elem[index] == e)
			break;
		index--;
	}
	return index;
}

//3:插入(在第i个位置插入元素e)
void listInsert(sqList &L, int i, elemtype e)
{
	if (i < 1 || i > L.length + 1) 
        {
		cout << "插入的位置不合理!" << endl;
		exit(0);
	}
	if (L.length >= L.listsize) 
        {
		elemtype *newbase;
		newbase = (elemtype *) realloc(L.elem,
				sizeof(elemtype) * (L.listsize + INCREMENT));
		if (newbase == NULL)
                {
			cout << "空间增加不成功!" << endl;
			exit(0);
		}
		L.elem = newbase;
		L.listsize += INCREMENT;
	}
	for(int j=L.length-1;j>=i-1;j--)
		L.elem[j+1]=L.elem[j];
	L.elem[i-1]=e;
	L.length++;
}

//4:追加(将元素插入到表尾)
void add(sqList &L, elemtype e) 
{
	if (L.length >= L.listsize) 
        {
		elemtype *newbase;
		newbase = (elemtype *) realloc(L.elem,
				sizeof(elemtype) * (L.listsize + INCREMENT));
		if (newbase == NULL) 
                {
			cout << "空间增加不成功!" << endl;
			exit(0);
		}
		L.elem = newbase;
		L.listsize += INCREMENT;
	}
	L.elem[L.length] = e;
	L.length++;
}

//5:删除(删除第i个数据元素,将元素的值通过变量e返回)
void listDelete(sqList &L, int i, elemtype &e)
{
	if(i<1||i>L.length)
        {
		cout<<"删除的元素不存在!"<<endl;
		exit(0);
	}
	e=L.elem[i-1];
	for(int j=i;j<=L.length-1;j++)
		L.elem[j-1]=L.elem[j];
	L.length--;
}

//6:遍历
void printList(sqList L) 
{
	for (int i = 0; i < L.length; i++) 
		cout << L.elem[i] << " ";
	cout << endl;
}

void listDeleteRepeat(sqList &L)
{
    int i = 0;
    while (i < L.length - 1)
    {
        if (L.elem[i] == L.elem[i + 1])
        {
            int e;
            listDelete(L, i + 1, e);
        }
        else
        {
            i++;
        }
    }
}

int main()
{
	sqList L;
	int n;
	cin>>n;
	int e;
	initList(L);
	for(int i=1;i<=n;i++)
        {
		cin>>e;
		add(L,e);
	}
	listDeleteRepeat(L);
	printList(L);
	return 0;
}

4.集合的并集
【问题描述】某两个集合中存放着若干整数,请求解这两个集合的并集,根据上下文,将程序补充完整。其中函数add实现将数据元素e追加到顺序表的表尾,函数listUnion实现将B集合在A集合中的不存在的数据并入到A集合中。

【输入形式】三行,第一行:两个集合中元素的个数;第二行:第一个集合中的元素以空格间隔;第三行:第二个集合中的数据以空格间隔

【输出形式】两个集合的并集

【样例输入】

3 5

1 2 3

1 3 5 7 9

【样例输出】1 2 3 5 7 9

【样例说明】第一个集合有3个整数,第二个集合中有5个整数,两个集合的并集是相同元素保留一份,不同元素并到结果中

#include <bits/stdc++.h>
using namespace std;
#define INCREMENT 2
struct SqList
{
    int *elem;
    int listsize;
    int length;
};
void initList(SqList &L,int n)
{
    L.elem=(int *)malloc(sizeof(int)*n);
    if(L.elem==NULL)
    {
        cout<<"failed";
        exit(0);
    }
    L.listsize=n;
    L.length=0;
}
void add(SqList &L, int e)
{
    if (L.length >= L.listsize)
    {
        int *newbase;
        newbase = (int *)realloc(L.elem, sizeof(int) * (L.listsize + INCREMENT));
        if (newbase == NULL)
        {
            exit(0);
        }
        L.elem = newbase;
        L.listsize += INCREMENT;
    }
    L.elem[L.length] = e;
    L.length++;
}

void createList(SqList &L,int n)
{
    int e;
    initList(L,n);
    for(int i=1; i<=n; i++)
    {
        cin>>e;
        add(L,e);
    }
}
int location(SqList L,int e)
{
    int index=L.length-1;
    while(index>=0)
    {
        if(L.elem[index]==e)
            break;
        index--;
    }
    return index;
}
void listUnion(SqList &La, SqList Lb)
{
    for (int i = 0; i < Lb.length; i++)
    {
        if (location(La, Lb.elem[i]) == -1)
        {
            
            add(La, Lb.elem[i]);
        }
    }
}
void printList(SqList L)
{
    for(int i=0; i<L.length; i++)
        cout<<L.elem[i]<<" ";
    cout<<endl;
}
int main()
{
    SqList La,Lb;
    int m,n;
    cin>>m>>n;
    createList(La,m);
    createList(Lb,n);
    listUnion(La,Lb);
    printList(La);
    return 0;
}

以上是在上个月学习数据结构时的总结,在以后的博客中可能会量会少很多。

  • 16
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XforeverZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值