数据结构--链表,栈,队列,二叉树,哈希表,快速排序

数据结构

数据结构分为三个方面逻辑结构、存储结构、数据运算
逻辑结构分为:线性结构和非线性结构
线性结构---(线性表)(栈)(队)
非线性结构--(树结构)(图形结构)
数据存储结构-(顺序存储)(链表存储)(索引存储)(散列存储)

数据运算----(排序)(插入)(删除)(修改)等

一、线性表

顺序存储:(优点)通过动态分配的一段连续地址进行存储,方法简单易实现

(缺点)在进行插入和删除的时候,移动的元素很多,如果插入或删除的元素较大的时候,效率低

链表存储:(优点)在链表中相邻的两个元素,物理地址不一定相邻,是通过动态分配的,运算快,效率高

(缺点) 要占用额外的存储空间存储元素之间的关系

1.顺序表(顺序存储)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct
{
        int * data;//存放数组第一个元素
        int cnt;//有效元素个数
        int len;//数组长度
}sx,*sx_p;

void show_sx(sx_p s);//遍历
void init_sx(sx_p s,int len);//开辟空间
void delete_sx(sx_p s,int pos,int *val);//删除
bool insert_sx(sx_p s,int pos,int val);//插入
bool add(sx_p s,int val);//添加
bool empty(sx_p s);//是否为空
bool full(sx_p s);//是否满
#include "sx.h"

void init_sx(sx_p s,int len)
{
        s->data = (int *)malloc(sizeof(int)*len);
        if(s->data == NULL)
        {
                printf("分配失败!\n");
                exit(-1);
        }
        else
        {
                s->cnt = 0;
                s->len = len;
                printf("分配成功--开辟了%d个字节\n",len);
        }

        return;
}

bool empty(sx_p s)
{
        if(s->cnt == 0)
        {
                printf("empty!\n");
                return true;
        }
        else
                return false;
}

bool full(sx_p s)
{
        if(s->cnt == s->len)
        {
                printf("Full!\n");
                return true;
        }
        else
                return false;

}

bool add(sx_p s,int val)
{
        if(full(s));

        s->data[s->cnt]=val;
        (s->cnt)++;
}

bool insert_sx(sx_p s,int pos,int val)
{
        if(full(s));
        if(pos<1 || pos>s->cnt+1)
        {
                printf("没找到该元素!\n");
                return false;
        }
        else
        {
                for(int i=s->cnt-1;i>=pos-1;i--)
                {
                        s->data[i+1]=s->data[i];
                }

                s->data[pos-1]=val;
                (s->cnt)++;
        }
}

void  delete_sx(sx_p s,int pos,int *val)
{
        if(empty(s));
        if(pos < 1 || pos >s->cnt)
        {
                printf("没找到要删除的元素\n");
                exit(-1);
        }
        else
        {
                *val=s->data[pos-1];

                for(int i=pos;i<s->cnt;i++)
                {
                        s->data[i-1]=s->data[i];
                }

                (s->cnt)--;

                return;
        }


}

void show_sx(sx_p s)
{
        if(empty(s));
        else
        {
                for(int i=0;i<s->cnt;++i)
                {
                        printf("%d ",s->data[i]);

                }
                puts("");
        }
}
#include "sx.h"

int main()                  
{
        sx s;                                    
        int val;           
        init_sx(&s,6);
                                      
        add(&s,1);       
        add(&s,2);
        add(&s,3);
        add(&s,4);
        add(&s,5);         
                             
        show_sx(&s);                                     
        insert_sx(&s,1,100);
        show_sx(&s);
               
        delete_sx(&s,1,&val);
        printf("删除的是:%d \n",val);
}

2.顺序表(离散存储/链表)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


typedef struct n
{
        int data;//数据域
        struct n * next;//指针域
}node,*pnode;


pnode create_node();//创建节点
void print(pnode p);//输出数据
void empty(pnode p);//判断是否空
int len_lb(pnode p);//有几个节点
bool insert(pnode p,int pos,int val);//插入
bool delete_lb(pnode p,int pos,int *val);//删除
#include "lb.h"

pnode create_node()
{
        int len,val;

        //创建头节点

        pnode head = (pnode)malloc(sizeof(node));
        if(head == NULL)
        {
                printf("头节点创建失败!\n");
                exit(-1);
        }

        //尾节点始终指向最后一个节点

        pnode last = head;
        last->next = NULL;

        //开始创建节点

        printf("您需要创建多少个节点: ");
        scanf("%d",&len);

        for(int i=0;i < len;++i)
        {
                printf("请输入第%d个节点的数据: ",i+1);
                scanf("%d",&val);

                pnode pnew = (pnode)malloc(sizeof(node));
                if(pnew == NULL)
                {
                        printf("新节点分配失败!\n");
                }

                pnew->data = val;
                last->next = pnew;
                pnew->next = NULL;
                last = pnew;
        }

        printf("---------------\n");

        //返回头节点

        return head;

}

void print(pnode phead)
{
        pnode head = phead->next;

        if(head == NULL)
        {
                printf("没有创建节点\n");
        }
        while(head != NULL)
        {
                printf("%d ",head->data);
                head=head->next;
        }

        puts("");

}
void empty(pnode p)
{
        if(p->next == NULL)
        {
                printf("链表为空\n");
                exit(-1);
        }
}

int len_lb(pnode p)
{

        int len = 0;

        while(p->next != NULL)
        {
                len++;
                p=p->next;

        }

        return len;
}
bool insert(pnode p,int pos,int val)
{
        int i = 0;

        while(p->next != NULL && pos-1 > i)
        {
                p=p->next;
                i++;
        }

        if(p->next == NULL || pos-1 < i)
        {
                printf("没找到该节点\n");
                return false;
        }

        pnode pnew = (pnode)malloc(sizeof(node));
        if(pnew == NULL)
        {
                printf("分配失败\n");
        }

        pnew->data = val;
        pnode old = p->next;
        p->next = pnew;
        pnew->next = old;

        return true;
}

bool delete_lb(pnode p,int pos ,int *val)
{
        int i = 0;
        while(p->next != NULL && pos-1 > i)//指向pos的这个位置
        {
                p=p->next;
                i++;
        }

        if(p->next == NULL || pos-1 < i)
        {
                printf("没找到该节点\n");
                return false;
        }

        pnode old = p->next;
        *val=old->data;
        p->next=p->next->next;

        free(old);//防止内存泄漏
        old = NULL;//防止野指针

        return true;

}
#include "lb.h"

int main()
{
        int cnt;
        int val = 0;

        pnode head;
        head=create_node();

        if(insert(head,2,100))
        {
                printf("插入成功\n");
        }

        print(head);

        if(delete_lb(head,1,&val))
        {
                printf("删除成功,删除的是: %d \n",val);
        }

        print(head);

        cnt = len_lb(head);
        printf("有%d个有效元素\n",cnt);

        return 0;
}

3.栈(栈也是一种存储方式,它采用的是先进后出原则)比如函数调用就运用的栈的方法

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


typedef struct node
{
        int data;
        struct node* next;

}node,*pnode;

typedef struct stack
{
        pnode top;
        pnode bottom;

}z,*sta;

void init_create(sta s);
void push(sta s,int val);
void print(sta s);
void pop(sta s,int *val);
void clear(sta s);
void init_create(sta s)
{

        s->top = (pnode)malloc(sizeof(node));
        if(s->top == NULL)
        {
                printf("分配内存失败\n");
                exit(-1);
        }

        s->bottom = s->top;

        return;
}

void push(sta s,int val)
{
        pnode pnew = (pnode)malloc(sizeof(node));
        if(pnew == NULL)
        {
                printf("分配内存失败\n");
                exit(-1);
        }
        else
        {
                pnew->data = val;
                pnew->next = s->top;
                s->top = pnew;
        }

        return;
}

void print(sta s)
{
        if(s->top == s->bottom)
        {
                printf("栈空\n");
                exit(-1);
        }

        pnode p = s->top;

        while(p != s->bottom)
        {
                printf("%d ",p->data);
                p=p->next;
        }

        puts("");

        return;
}

void pop(sta s,int *val)
{
        if(s->top == s->bottom)
        {
                printf("empty\n");
                exit(-1);
        }
        pnode p = s->top;
        *val = p->data;
        s->top = p->next;
        free(p);
}

void clear(sta s)
{
        if(s->top == s->bottom)
        {
                printf("empty\n");
                exit(-1);
        }

        pnode p = s->top;
        pnode q = NULL;
        while(p != s->bottom)
        {
                q=p->next;
                free(p);
                p = q;
        }

        s->top = s->bottom;
}           
#include "z.h"

void main()
{

        z s;
        int val;

        init_create(&s);
        push(&s,1);
        push(&s,2);
        push(&s,3);
        push(&s,4);
        push(&s,5);
        push(&s,6);

        print(&s);

        pop(&s,&val);
        printf("出站的是: %d \n",val);

        print(&s);
        printf("栈已清除\n");
        clear(&s);
        print(&s);
}

4.队列(队列特点是先进先出,可以分为动态队列,和静态)一般应用于关于时间的地方

静态队列必须用循环队列来实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct que
{
        int *data;
        int front;
        int back;
}QUE;

void init(QUE * p);
void print(QUE * p);
void add(QUE *p,int val);
void out(QUE * p,int *val);
#include "que.h"

void main()
{
        QUE que;
        int val;

        init(&que);

        add(&que,1);
        add(&que,2);
        add(&que,3);
        add(&que,4);
        add(&que,5);

        print(&que);

        out(&que,&val);
        printf("出队的是:%d \n",val);

        print(&que);
}
#include "que.h"


void init(QUE * p)
{
        p->data = (int *)malloc(sizeof(int )*6);
        if(p->data == NULL)
        {
                printf("分配失败\n");
                exit(-1);
        }
        else
        {
                p->front = 0;
                p->back = 0;
        }

        return;

}

void print(QUE * p)
{
        if(p->front == p->back)
        {
                printf("空的\n");
                exit(-1);
        }
        else
        {
                int i = p->front;

                while( i != p->back)
                {
                        printf("%d ",p->data[i]);
                        i = (i +1)%6;
                }

                puts("");
        }

        return;
}

void add(QUE * p,int val)
{
        if(p->front == (p->back + 1)%6)
        {
                printf("满的\n");
                exit(-1);
        }
        else
        {
                p->data[p->back] = val;
                p->back = (p->back+1 )%6;

        }

        return;
}

void out(QUE * p,int *val)
{

        if(p->front == p->back)
        {
                printf("空的\n");
                exit(-1);
        }

        else
        {
                *val = p->data[p->front];
                p->front = (p->front + 1)% 6;


        }
}

链式队列

#include <stdio.h>

typedef struct  stu 
{
	int data;
	struct stu * next;
}*pnode,node;

typedef struct
{
	pnode front;
	pnode rear;

}*p;

void init(p p1)
{
	p1->rear = p1->front = NULL;
	
}

void rudui(p p1,int data)
{
	p new = (pnode)malloc(sizeof(node));
	if(new == NULL)
	{
		printf("创建节点失败\n");
		exit(-1);
	}
	
	new->data = data;
	new->next = NULL;
	
	if(p1->rear == NULL)
	{
		p1->rear = new;
		p1->front = new;
	}
	else
	{	
		p1->rear->next = new;
		p1 = new;
	}

}

void chudui(p p1,int * val)
{
	if(p1->rear == NULL)
	{
		printf("队列是空得\n");
	
	}
	pnode tmp = p1->front;
	*val = tmp->data;
	free(p1->front);
	p1->front = tmp->next;

}

void print(p p1)
{
	if(p1->rear == NULL)
	{
		printf("队列为空\n");
	}
	while(p1->rear)
	{
		printf("%d\n",p1->rear->data);
		p1->rear = p1->rear->next;
	}

}

void clear(p1 p)
{
	if(p1->rear == NULL)
	{
		printf("队列为空\n");
	}
	
	pnode tmp = p1->rear;
	pnode ttmp = NULL;
	while(p1->rear)
	{
		ttmp = tmp->next;
		free(tmp);
		tmp = ttmp;
	
	}
	

}

5.递归

递归的定义:自己调用自己

递归的应用:用于树,图,和一些数学算法,斐波那契数列 

递归的方法:

1.必须有条件限制

2.必须数据规模是在递减

3.可以循环的代码一定可以用递归,但是递归的代码不一定用于循环

调用函数时:先把实际参数和下一个要执行的指令地址传给被调函数,被调函数的形参分配内存,返回运算的结果,并执行下一条指令,释放内存

#include <stdio.h>

/*阶乘*/

int jc(int i)
{
        if(i == 1)
        {
                return 1;
        }
        else
        {
                return i*jc(i-1);
        }
}



void main()
{
        int i;
        int s;

        printf("请输入你需要求的阶乘数字: ");
        scanf("%d",&i);

        s = jc(i);
        printf("%d的阶乘是%d\n",i,s);
}

6.二叉树

通过先序(根左右),中序(左根右),后序(左右根)遍历,一般是用先序进行创建,一个二叉树至少有一个节点(树),每个节点都有两个分支叫做满二叉树,一个分支是完全二叉树,二叉树用于存放非线性得数据,比如Linux的文件系统。

先中序遍历

#include <stdio.h>

typedef struct node
{
	char data;
	struct node * left;
	struct node * right;
	
}*ptree,tree;

ptree init()
{
	char ch;
	printf("创建你的树\n");
	scanf("%d",&ch);
	if(ch == '#')
	{
		return NULL;
	}
	ptree s;
	if((s = (tree)malloc(sizeof(tree))) == NULL)
	{
		printf("创建树失败\n");
		return NULL;
	}
	
	s->data = ch;
	s->left = init();
	s->right = init();
	
	return r;
	
}

void xianxu(ptree p1)
{
	if(p1 == NULL)
	{
		printf("没有树\n");
	}
	
	printf("%d\n",p1->data);
	xianxu(p1->left);
	xianxu(p1->right);
}
void zhongxu(ptree p1)
{
	if(p1 == NULL)
	{
		printf("没有树\n");
	}
	
	
	zhongxu(p1->left);
	printf("%d\n",p1->data);
	zhongxu(p1->right);
}
void hoxun(ptree p1)
{
	if(p1 == NULL)
	{
		printf("没有树\n");
	}
	
	hoxun(p1->left);
	hoxun(p1->right);
	printf("%d\n",p1->data);

}

层次遍历(要用到队列)每次访问一个入队列,在出队列~(创建同上)

#include <stdio.h>

typedef struct  stu 
{
	int data;
	struct stu * next;
}*pnode,node;

typedef struct
{
	pnode front;
	pnode rear;

}*p;

void init(p p1)
{
	p1->rear = p1->front = NULL;
	
}

void rudui(p p1,ptree p2)
{
	p new = (pnode)malloc(sizeof(node));
	if(new == NULL)
	{
		printf("创建节点失败\n");
		exit(-1);
	}
	
	new->data = p2->data;
	new->next = NULL;
	
	if(p1->rear == NULL)
	{
		p1->rear = new;
		p1->front = new;
	}
	else
	{	
		p1->rear->next = new;
		p1 = new;
	}

}

void chudui(p p1)
{
	if(p1->rear == NULL)
	{
		printf("队列是空得\n");
	
	}
	pnode tmp = p1->front;
	//*val = tmp->data;
	free(p1->front);
	p1->front = tmp->next;

}
int empty(p p2)
{
	if(p2->rear == NULL)
	return null;
}

//层次遍历
void cenci(ptree p1)
{
	p p2 = init(p2);
	
	printf("%d\n",p1->data);
	rudui(p2,p1);
	
	while(!empty(p2))
	{
		chudui(p1);
		if(p1->left)
		{
			printf("%d\n",p1->left->data);
			rudui(p2,p1);
		}
		if(p1->right)
		{
			printf("%d\n",p1->right->data);
			rudui(p2,p1);
		}
	}
	
}

7.快速排序

快速排序先找一个基准,使基准左边比基准小,基准右边比基准大,一般拿第一个元素作为基准;

规则:j 找 比 基准小的放到 i 中

i 找 比 基准大的放到 j 中

i = j,把基准放到空位

#include <stdio.h>

void main()
{
	int arry[5] = {5,4,3,2,1};
	
	sort(arry,0,4);
}

void sort(int arry[],int i,int j)
{
	if(i > j)
	{
		return;
	}
	
	int p = arry[0];
	
	while(i < j)
	{
		while(i < j && arry[j] >= p)
		j--;
		arry[i] = arry[j];
		while(i < j && arry[i] <= p)
		i++;
		arry[j] = arry[i];
	}
	
	arry[i] = p;
	sort(arry,i,i-1);
	sort(arry,i+1,j);
}

8.哈希表(数组+链表)

哈希表是一中查找的方法,通过一个key快速找到数据对应的位置,就比如通讯录,你想找一个王二,那就可以通过w来锁定位置,而w就是哈希函数,可以通过除数取余法得到 key = key % n, n<=p (p为表长),但是假如找一个王三的人,他们都是w,那就形成了哈希冲突,通过链地址法就行处理,也就是把相同的进行从小到大排列。

#include <stdio.h>
#define N 15

typedef struct node
{
	int data;//存放数据
	inte key;//键值
	struct node * next;
}*pnode,node;
typedef struct hx
{
	node data[N];
}*pht,ht;

pht create()
{
	pht hx = (pht)malloc(sizeof(ht));
	if(hx == NULL)
	{
		printf("创建哈希表失败\n");
	}
	
	memset(hx,0,sizeof(ht))
	
	return hx;
}

void insert(pht hx,int data)//插入
{
	if(hx == NULL)
	return;
	
	pnode q;
	pnode new = (pnode)malloc(sizeof(node));
	
	new->data = data;
	new->key = key % 13;
	new->next = NULL;
	
	q = &(hx->data[key % 13]);//指向哈希key地址
	
	while(q->next && q->next->data < new->data)//解决哈希冲突
	{
		q = q->next;
	}
	new->next = q->next;
	q->next = new;
}

pth search(pth hx,int data)
{
	if(hx == NULL)
	return;
	
	while(hx->next && hx->next->data != data)
	{
		hx = hx->next;
	}
	if(hx->next == NULL)
	{
		return;
	}
	else
	{
		printf("found!\n");
		return hx->next;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

No Iverson

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

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

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

打赏作者

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

抵扣说明:

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

余额充值