数据结构个人笔记

本文深入探讨了数据结构中的二叉树类型,包括完全二叉树、平衡二叉树和哈希查找。阐述了排序算法,如冒泡排序、快速排序和插入排序,并讲解了查找技术,如顺序查找和哈希表。此外,还介绍了链表、栈和队列等基础数据结构及其应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


基本概念

b615202d504441b79ec297840a20b685.png

 数据:描述客观事物的符号(名字,年龄大小,人物关系,都用符号来表示)
 数据对象:具有相同数据特征的数据的集合(Excel里的人员表)
 数据元素:数据的基本单位(Excel表里的一行,某个人)
 数据项:构成数据元素的最小单位(每一行的一个表格,某个人的学号)

绪论

空间复杂度

O(1):不需要辅助空间

递归函数的空间复杂度

递归函数的参数和局部变量占用的内存空间 随着递去增长,随着归来减小,若递到一定深度时,可能会造成内存空间不足。

算法的原地工作:需要的辅助空间为O(1)(例如:总是只需要100个int的辅助变量就能执行这个程序,强调空间不是时间)

0528e8978678c00863ae40ea92e0ee00.png

O(n)是数组总量,O(n/2)是递归的平均量 O(n)是最后一个数组总量,O(n/2)是递归的平均量

线性表

顺序表:(静态)数组和动态数组

优点:随机存储快O(1);存储密度大 缺点:插入删除要移动大量元素;要预先分配空间;容量难以扩充。

C++顺序表的实现

动态数组:指针                        数组大小

                  arr                               size

定义         *arr                          int size

初始化      arr= new []                   size=0

#include<iostream>
using namespace std;

#define MAXSIZE 10
#define ERROR -1
typedef int INT;

//顺序表的定义
struct Sqlist
{
	INT* arr;//动态数组   INT arr[MAXSIZE];//静态数组	
	int size;

	Sqlist();//构造函数
	~Sqlist();//析构函数
	void InsertElem(int i, INT e);//增	 
	void DeleteElem(int i);//删
	INT GetElem(int i);//查
	void AlterElem(int i, INT e);//改
};

//顺序表的初始化
Sqlist::Sqlist()
{
	arr = new INT[MAXSIZE];//分配动态数组的内存空间; 静态数组不用
	if (!arr)exit(0);
	size = 0;
}

//顺序表的删除
Sqlist:: ~Sqlist()
{
	if (arr)
    {
        delete[] arr;
	    arr = nullptr;
    }	
    size = 0;
}

//任意位置插入
void Sqlist::InsertElem(int i, INT e)
{
	if (i<0 || i>size)return;//检查插入序号是否超过数组,数组值=m最后一位+1
	if (size == MAXSIZE)return;//检查数组大小是否超过开辟的最大长度
	for (int j = size - 1; j >= i; j--)//j从最后一位开始,到第i位完成为止
	{
		arr[j + 1] = arr[j];//把前一位赋给后一位
	}
	arr[i] = e;//把新元素插入第i号位
	size++;//数组加一
}
//任意位置删除
void Sqlist::DeleteElem(int i)
{
	if (i<0 || i>size - 1)return;
	for (; i < size - 1; i++)//i从第i位,到倒数第二位
	{
		arr[i] = arr[i + 1];//把后一位赋给前一位
	}
	size--;//数组减一
}


//按序号返回元素
INT Sqlist::GetElem(int i)
{
	if (i<0 || i>size - 1)return ERROR;
	return arr[i];
}
//改
void Sqlist::AlterElem(int i, INT e)
{
	if (i<0 || i>size - 1)return;
	arr[i] = e;
}

//打印
void Print(Sqlist& L);

void main()
{
	Sqlist L;//声明

	cout << L.GetElem(0); //查
	L.InsertElem(0, 1);  //增
	L.AlterElem(0, 2);	  //改
	L.DeleteElem(0);	  //删

	L.~Sqlist();//析构
}

void Print(Sqlist& L)
{
	for (int i = 0; i < L.size; i++)
	{
		cout << L.arr[i] << " ";
	}cout << endl;
}

//来点C语言风格的

#include<iostream>
using namespace std;

#define MAXSIZE 10
#define ERROR -1
typedef int INT;

//顺序表的定义
 typedef struct
{
     INT* arr;//动态数组   INT arr[MAXSIZE];//静态数组    
     int size;
 }Sqlist;

 //顺序表的初始化
 bool InitList(Sqlist& L)
 {
     
     L.arr = new INT[MAXSIZE];//分配动态数组的内存空间; 静态数组不用
     if (!L.arr)exit(0);
     L.size = 0;
     return 1;
 }

 //顺序表的删除
 void DestList(Sqlist &L)
 {
     if (L.arr)delete[] L.arr;
     L.arr = nullptr;
     L.size = 0;
 }

 //增
 void InsertElem(Sqlist &L,int i,INT e)
 {
     if (i<0 || i>L.size)return;//检查插入序号是否超过数组,数组值=m最后一位+1
     if (L.size == MAXSIZE)return;//检查数组大小是否超过开辟的最大长度
     for (int j = L.size - 1; j >= i; j--)//j从最后一位开始,到第i位完成为止
     {
         L.arr[j+1] = L.arr[j];//把前一位赋给后一位
     }
     L.arr[i] = e;//把新元素插入第i号位
     L.size++;//数组加一
 }
 //删
 void DeleteElem(Sqlist& L, int i)
 {
     if (i<0 || i>L.size - 1)return;
     for (; i < L.size-1; i++)//i从第i位,到最后一位
     {
         L.arr[i] = L.arr[i+1];//把后一位赋给前一位
     }
     L.size--;//数组减一
 }


 //查
 INT GetElem(Sqlist &L, int i)
 {
     if (i<0 || i>L.size-1)return ERROR;
     return L.arr[i];
 }
 //改
 void AlterElem(Sqlist& L, int i ,INT e)
 {
     if (i<0 || i>L.size - 1)return;
     L.arr[i] = e;
 }

 //打印
 void Print(Sqlist& L);

void main()
{
    Sqlist L;//声明
    InitList(L);//初始化

    InsertElem(L, 0, 1);  //增
    cout << GetElem(L, 0);//查
    AlterElem(L, 0, 2);      //改
    DeleteElem(L, 0);      //删

    DestList(L);//析构
}

void Print(Sqlist& L)
{
    for (int i = 0; i < L.size; i++)
    {
        cout << L.arr[i] << " ";
    }cout << endl;
}

链表

#include<iostream>
using namespace std;

#define ERROR -1
typedef int INT;

//结点的定义
typedef struct Node
{
	INT data = 0;//数据域
	Node* next;//指针域

	Node() :next(nullptr) {};//构造函数
	Node(INT v) :data(v), next(nullptr) {};//有参构造
}Lnode,  *LinkList;
/*对象别名 指针别名   用法Lnode L通常指向结点, LinkList L通常指向链表*/

//链表的定义
typedef struct List
{
	List();
    ~List();
//增
    void addAtHead(INT data);//头插
    void addAtTail(INT data);//尾插
    void addAtIndex(int index, INT data);//任意插
//删
    void deleteAtIndex(int index);
//查
	INT get(int index);
private:
	Node* head;//头结点
	int size;
};


//链表的初始化
List::List()
{
	head = new Node;
	size = 0;
}

//链表的销毁
List::~List()
{
    Node* cur;
    while(head)
    {
        cur = head;
        head = head->next;
        delete cur;
    }
}

//头插
void List::addAtHead(INT data) {
    Node* newNode = new Node(data);
    {
        newNode->next = head->next;
        head->next = newNode; }
        size++;
}

//尾插
void List::addAtTail(INT data) {
    Node* cur = head;
    while (cur->next)//while(size--)
    {
        cur = cur->next;
    }
    Node* newNode = new Node(data);
    cur->next = newNode;
    newNode->next = nullptr;
    size++;
}

//任意位置插
void List::addAtIndex(int index, INT data) {
    if (index<0 || index>size)return;
    else if (index == 0)addAtHead(data);
    else if (index == size)addAtTail(data);
    else
    {
        Node* cur = head;
        while (index--)//如果你要指到第0号元素,你就不需要移动,index=0
        {
            cur = cur->next;
        }
        Node* newNode = new Node(data);
        newNode->next = cur->next;
        cur->next = newNode;
        size++;
    }
}

//任意位置删除
void List::deleteAtIndex(int index) {
    if (index < 0 || index >= size) return;
    Node* cur = head;//从头指针开始
    while (index--) {//遍历到index-1的位置,循环次数是index次
        cur = cur->next;
    }
    cur->next = cur->next->next;//相当于直接跨过了index节点
    size--;
}

//查找
INT List::get(int index) {
    if (index < 0 || index >= size)
    {
        return ERROR;
    }
    Node* cur = head;
    while (index--)
    {
        cur = cur->next;
    }
    return cur->next->data;//改的话,就把这里换成cur->next->data = 传入的元素;
}

int main()
{

	return 0;
}

顺序栈

索引值:(第一个元素索引值为0)

        栈空:top== - 1 
        栈满:top==Maxsize-1

指针:有top、base指针(为了方便通常top指向栈顶元素的上方,base指向栈底元素)

        栈空:top==base
        栈满:top-base=Maxsize(top会指针栈外面)
     (指针是可以±的)
     如果两个指针向同一个数组,它们就可以相减,其为结果为两个指针之间的元素数目

上溢(overflow):满栈还push
下溢(underflow):空栈还pop

顺序栈代码

 top指向栈顶元素

#include<iostream>
using namespace std;

#define MAXSIZE 10
#define ERROR -1
typedef int INT;

struct SqStack
{
	INT* arr;//栈顶指针
	int top;//栈顶指针

	int size;

	SqStack();
	~SqStack();
	void Push(INT e);
	INT Pop();
    INT GetTop();
	void ClearStack();
	bool IsStackEmpty();

};

SqStack::SqStack()
{
	arr= new INT[MAXSIZE];//开辟一个数组
	if (arr)
	{
		top = -1;//栈空
		size = 0;
	}
}

SqStack::~SqStack()
{
	if (arr)
	{
		delete[] arr;
		arr = nullptr;
        top = -1;
		size = 0;
	}
}

void SqStack::Push(INT e)
{
	if (top == MAXSIZE - 1)return;
	arr[++top] = e;
	size++;
}

INT SqStack::Pop()
{
	if (top == -1)return INT_MIN;
	size--;
	return arr[top--];
}

INT SqStack::GetTop()
{
    if(IsStackEmpty()) return ERROR;
    else return arr[top];
}

void SqStack::ClearStack()
{
	if (arr)
	{
		top = -1;
		size = 0;
	}
}

bool SqStack::IsStackEmpty()
{
	if (top == -1)return true;
	else return false;
}

top指向栈顶元素的上方

#include<iostream>
using namespace std;

#define MAXSIZE 10
#define ERROR -1
typedef int INT;

struct SqStack
{
	INT* base;//栈顶指针
	INT* top;//栈顶指针

	int size;

	SqStack();
	~SqStack();
	void Push(INT e);
	INT Pop();
    INT GetTop();
	void ClearStack();
	bool IsStackEmpty();

};

SqStack::SqStack()
{
	base = new INT[MAXSIZE];//开辟一个数组
	if (base)
	{
		top = base;//栈空
		size = 0;
	}
}

SqStack::~SqStack()
{
	if (base)
	{
		delete[] base;
		top = base = null
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值