C语言-数据结构

数据结构

第一章 概论

1.常用的数据结构类型:集合线性树形图状

2.数据结构:

  • 逻辑结构:数据元素之间的关系。
  • 存储结构:数据结构在计算机中的表示。存储结构分为:顺序存储结构和链式存储结构。

3.算法是对特定问题求解步骤的一种描述,算法具有如下特性:有穷性、确定性、可行性、输入、输出。

4.算法的度量:

  • 时间复杂度
  • 空间复杂度

第二章 线性表

●顺序表

#include<stdio.h>
#include<stdlib.h>
#define maxsize 1024

typedef int datatype;
//定义顺序表结构体类型
typedef struct
{
	datatype elem[maxsize];
	int length;
}sequenlist;
sequenlist *L;

//初始化表
void InitList(sequenlist *L)
{
	L->length=0;
}

//清空表 
void ClearList(sequenlist *L)
{
	L->length=0;
}

//元素定位 
int Loc(sequenlist *L,datatype item)
{
	int i,j;
	j=(*L).length;
	if(j==0)return false;
	for(i=0;i<j;i++)
	{
		if((*L).elem[i]==item)return i;
	}
	printf("元素未找到!");
	return -1;
}


//元素插入 
int Ins(sequenlist *L,int i,datatype item)
{
	int j;
	if(i<1||i>(*L).length)return false;
	for(j=(*L).length;j>i;j--)(*L).elem[j]=(*L).elem[j-1];
	(*L).elem[i]=item;
	(*L).length++;
	return true;
}

//删除元素 
int Del(sequenlist *L,int i)
{
 
	int j;
	if(i<1||i>(*L).length)return false;
	for(j=i;j<(*L).length;j++)(*L).elem[j]=(*L).elem[j+1];
	(*L).length--;
	return true;
}

//添加元素
void createlist(sequenlist *L)
{
	int n,i,c_type;
	printf("请输入元素个数:");
	scanf("%d",&n);
	printf("请输入元素:\n");
	for(i=0;i<n;i++)
	{
		printf("elem[%d]=",i);
		fflush(stdin);
		scanf("%d",&(*L).elem[i]);
		printf("\n");
	}
	(*L).length=n;
}

//打印函数 
void printout(sequenlist *L)
{
	int i;
	printf("--------当前表已更新--------\n");
	for(i=0;i<(*L).length;i++)
	printf("elem[%d]=%d                  -\n",i,(*L).elem[i]);
	printf("----------------------------");
	printf("\n\n\n");
 
 
 
};

//主函数
int main()
{
	int button,e,w;
	L=(sequenlist *)malloc(sizeof(sequenlist));
	printf("4*1024+4=%d (64位系统 int 4 字节)\n",sizeof(int)*1024+sizeof(int));
	printf("the byte of sequenlist:%d\n",sizeof(sequenlist));
	createlist(L);

printf("-------------------菜单-------------------\n");
printf("1.元素定位 2.元素插入 3.元素删除 4.表查询\n");
while(true){
printf("功能选择:");
scanf("%d",&button);
switch(button){
	case 1:printf("请输入元素:");
	scanf("%d",&e);
	printf("元素下标为:%d\n",Loc(L,e));
	printout(L);
	break;
	case 2:printf("请输入元素:");
	scanf("%d",&e);
	printf("请输入元素插入的位置:");
	scanf("%d",&w);
	Ins(L,w,e);
	printout(L);
	break;
	case 3:printf("请输入元素下标:");
	scanf("%d",&e);
	Del(L,e);
	printout(L);
	break;
	case 4:printout(L);} 
 }
}

链表
●单链表

#include<stdio.h>
#include<stdlib.h>
typedef char elemtype;

//结点的数据类型定义
typedef struct LNode
{
	elemtype data;
	struct LNode *next;
}LinkList;
LinkList *L,*head;

//清空链表内容
int ClearList(LinkList *L)
{
	LinkList *temp;
	while(L->next!=NULL)
	{
		temp=L->next;
		L->next=L->next->next;
		free(temp);
	}
}

//求链表长度 
int ListLength(LinkList *L)
{
	int len=0;
	LinkList *temp;
	temp=L;
	while(temp->next!=NULL)
	{
		len++;
		temp=temp->next;
	}
	return len;
}

//元素定位
int Loc(LinkList *L,elemtype item)
{
	int i=0;
	LinkList *temp;
	temp=L->next;
	while(temp!=NULL&&temp->data!=item)
	{
		i++;
		temp=temp->next;
	}
	if(temp==0)return 0;
	else return i;
}

//插入元素
int Ins(LinkList *L,int i,elemtype item)
{
	int j=1;
	LinkList *node,*temp;
	node=(LinkList *)malloc(sizeof(LinkList));
	if(node==NULL)return -1;
	node->data=item;
	temp=L->next;
	if(temp==NULL)
	{
		if(i==0)
		{
			L->next=node;
			node->next=NULL;
			return 1;
		}
		else return -1;
	}
	while(j<i&&temp!=NULL)
	{
		temp=temp->next;
		j++;
	}
	if(temp==NULL)return -1;
	node->next=temp->next;
	temp->next=node;
	return 1;
}

//删除元素
int Del(LinkList*L,int i) 
{
	LinkList *temp,*p;
	int j=1;
	temp=L;
	if(temp==NULL)return false;
	while(j<i-1&&temp!=NULL)
	{
		j++;
		temp=temp->next;
	}
	if(temp==NULL&&temp->next==NULL)return false;
	p=temp->next;
	temp->next=temp->next->next;
	free(p);
	return true;
}

//主函数
int main()
{
	int s;
	int item,i; 
	LinkList *L;
	L=(LinkList *)malloc(sizeof(LinkList));
while(1)
{
	printf("\n-----------------线性表-单链表---------------------");
	printf("\n1.插入(以0开始) 2.定位 3.删除 4.求链表长度 5.清空链表");
	printf("\n请选择功能:");
	scanf("%d",&s);
	if(s==1){
		printf("请输入插入的数据:");
		scanf("%d",&item);
		printf("\n请输入插入的位置:");
		scanf("%d",&i);
		Ins(L,i,item);
		printf("插入成功!");
		fflush(stdin);
}
	else if(s==2){
		printf("请输入定位的数据:");
		scanf("%d",&item);
		printf("元素位置:%d",Loc(L,item));
		Loc(L,item);

	}
	
	else if(s==3){
		printf("请输入要删除的数据:");
		scanf("%d",&item);
		Del(L,item);
		printf("删除成功!");
		
	}
	else if(s==4){
		printf("当前链表的长度为:%d",ListLength(L));
		
		
	}
	else if(s==5){
		ClearList(L);
		printf("链表已清空!");
		
	}
	else printf("error!");
}
}

●循环链表

●双链表

第三章 栈与队列

●链栈
●顺序栈

#include<stdio.h>
#include<malloc.h>
#define maxsize 100
typedef int datatype;
typedef struct
{
	datatype stack[maxsize];
	int top;
}SeqStack;

//构造一个空栈
SeqStack *InitStack()
{
	SeqStack *s;
	s=(SeqStack *)malloc(sizeof(SeqStack));
	if(!s){
		printf("空间不足!");
		return NULL; 
	}
	else{
		s->top=0;
		return s;
	}
 } 

//取栈顶元素
datatype GetTop(SeqStack *s)
{
	if(s->top==0){
		printf("栈是空的!");
		return true;
	}
	else{
	return s->stack[s->top-1];//小心越界 
	}	
}

//入栈
SeqStack *Push(SeqStack *s,datatype x)
{
	if(s->top==maxsize){
		printf("栈是满的!");
		return NULL; 
	}
	else{
		s->stack[s->top++]=x;
	}
}

//出栈
SeqStack *Pop(SeqStack *s)
{
	if(s->top==0){
		printf("栈是空的!");
		return false;
	}
	else
	{
		s->stack[(s->top)--];
		return (SeqStack *)s->stack[s->top];
	}
}

//判别空栈 
int StackEmpty(SeqStack *s)
{
	if(s->top==0){
		printf("栈是空的!");
		return true;
	}
	else return false;
}

//打印栈元素
void PrintElem(SeqStack *s)
{
	int t;
	t=s->top;
	if(s->top==0)printf("the stack is empty!");
	else
	while(t!=0)
	{
		printf("%d->",s->stack[--t]);
	}
 }
 
//主函数
int main(){
    	int n,choice,e;
    	int a[n],i;
    	SeqStack *p;
    	p=InitStack();
    	printf("----------------------栈-顺序栈----------------------\n"); 
    	printf("请输入入栈的元素个数:");
    	scanf("%d",&n);
    	for(i=0;i<n;i++)
    	{
    		printf(">>[%d]=",i+1);
    		scanf("%d",&a[i]);
    	}
    	for(i=0;i<n;i++)Push(p,a[i]);
    	printf("output the stack values:");
    	PrintElem(p);
    	printf("\n");
    	printf("the stacktop value is %d",GetTop(p));
    	while(1){
    	printf("\n--------------------------------------");
    	printf("\n1.入栈 2.出栈 3.判断栈是否空 4.取栈顶元素 \n"); 
    	printf("请输入>>:");
    	scanf("%d",&choice);
    	switch(choice){
    		case 1:printf("请输入入栈元素:");scanf("%d",&e);Push(p,e);PrintElem(p);break;
    		case 2:printf("元素:%d 已出栈!\n",Pop(p));PrintElem(p);break;
    		case 3:printf("栈空:%d",StackEmpty(p));break;
    		case 4:printf("栈顶元素:%d",GetTop(p));break;
    	}
               }
    }

●顺序队列

●链队列

第四章 串

第五章 多维数组与广义表

第六章 树和二叉树

二叉树的定义和基本操作
1.二叉树的定义

  • n(n>=0)个结点的有限集T构成,由左右子树组成,且左右子树都为二叉树。n=0时为空树。

2.二叉树分类

  • 满二叉树 :一棵深度为k且有2^k -1个结点的二叉树。
  • 完全二叉树:叶子结点只能出现在层次最大的两层上出现,和满二叉树的结点一一对应,当右分支层次为p时,左分支层次为p或p+1。

3.二叉树的性质

  1. 在二叉树的第i层上至多有2^(i-1)个结点(i>=1)
  2. 深度为k的二叉树至多有2^k -1个结点(k>=1)
  3. n0=n2+1(n0为子叶结点数 n2为度为2的结点数)
  4. 具有n个结点的完全二叉树的深度为[log2 n]+1
  5. 对于有n个结点的完全二叉树,对任意结点i(1<=i<=n)
    ●i=1时,i是二叉树的根,无双亲;i>1时,双亲是[i/2]
    ●2i>n时,结点无左孩子;2i<=n时,左孩子为2i
    ●2i+1>n时,结点无右孩子,2i+1<=n时,右孩子为2i+1

二叉树的储存结构

  • 顺序储存结构:先补齐为完全二叉树,然后用数组按层储存。
  • 链式储存结构:二叉树链表存储的数据类型定义。

二叉树的遍历和线索化
●二叉树的遍历和树的高度计算

#include <stdio.h>
#include <stdlib.h>
//二叉树类型定义
typedef struct btnode
{
    int data;
    struct btnode *lchild,*rchild;
}btnode,*btree;

//建立二叉树
btnode *createtree()
{
    btree t;
    char p;
    p=getchar();
    if (p=='#')
    t=NULL;
    else
    {
        t=(btree)malloc(sizeof(btnode));
        t->data=p;
        t->lchild=createtree();
        t->rchild=createtree();
    }
    return t;
}

//按先序遍历
void preorder(btree root)
{
    if (root!=NULL)
    {
        printf("%c",root->data);
        preorder(root->lchild);
        preorder(root->rchild);
    }
}

//按中序遍历
void inorder(btree root)
{
     if (root!=NULL)
    {
        inorder(root->lchild);
        printf("%c",root->data);
        inorder(root->rchild);
    }
}

//按后序遍历
void postorder(btree root)
{
    if (root!=NULL)
    {
        postorder(root->lchild);
        postorder(root->rchild);
        printf ("%c",root->data);
    }
}

//计算二叉树的高度
int depth(btree t)
{
    if (t==NULL)
    return 0;
    else
    {
        int h1,h2,h;
        h1=depth(t->lchild);
        h2=depth(t->rchild);
        if (h1>h2)
        h=h1+1;
        else
        h=h2+1;
        return h;
    }
}

//主函数
int main()
{
   btree t;
   t=createtree();
   printf("输入二叉树的先序排列(空的地方输入#):");
   printf("按先序遍历二叉树\n");
   preorder(t);
   printf ("\n");
   printf("按中序遍历二叉树\n");
   inorder(t);
   printf ("\n");
   printf("按后序遍历二叉树\n");
   postorder(t);
   printf ("\n");
   printf ("树的深度\n");
   printf ("%d\n",depth(t));

    return 0;
}

线索二叉树
根据先根遍历和中根遍历画树

第七章 图

图的邻接表存储及遍历

#include<stdio.h>
#include<stdlib.h>
#define MAX 20
typedef int VexType;
typedef struct Vnode
{
  VexType data;
  struct Vnode * next;
}Vnode;
typedef Vnode Lgraph[MAX];
typedef struct{
    int V[MAX];
    int front;int rear;
}Queue;

/* 函数原型声明确规定*/
void creat_L(Lgraph G);
void output_L(Lgraph G);
void dfsL(Lgraph G,int v);
void bfsL(Lgraph G,int v);
Lgraph Ga;
int n,e,visited[MAX];

/*主函数,此部分代码要求手工输入*/
int main()
{
    int v1,i;
    for(i=0;i<MAX;i++) visited[i]=0;
    creat_L(Ga);
    output_L(Ga);
    printf("please enter the start vex in depth first search:\n");
    scanf("%d",&v1);
    printf("the result of the depth first search:\n");
    dfsL(Ga,v1);
    for(i=0;i<MAX;i++) visited[i]=0;
    printf("\nplease enter the start vex in breadth first search:\n");
    scanf("%d",&v1);
    printf("\nthe result of the breadth first search:\n");
    bfsL(Ga,v1);
}

/*建立无向图的邻接表,此部分代码要求手工输入*/
void creat_L(Lgraph G)
{
    Vnode *p,*q;
    int i,j,k;
    printf("\nplease enter the number of the vex and edge\n");
    scanf("%d,%d",&n,&e);
    for(i=1;i<=n;i++){G[i].data=i;G[i].next=NULL;}
    for(k=1;k<=e;k++)
    {
        printf("please enter each edge just like 1,2\n");
        scanf("%d,%d",&i,&j);
        p=(Vnode *)malloc(sizeof(Vnode));
        p->data=i;
        p->next=G[j].next; 
       G[j].next=p	               ;  /*p结点链接到第j条链*/
        q=(Vnode *)malloc(sizeof(Vnode));
        q->data=j;
        q->next=G[i].next; 
         G[i].next=q                 ; /*q结点链接到第i条链*/
    }
}


/*邻接表的输出,此部分代码要求手工输入*/
void output_L(Lgraph G)
{
    int i;
    Vnode *p;
    for(i=1;i<=n;i++)
    {
        printf("\nthe vertics which related to[%d] is:",i);
        p=G[i].next;
        while(p!=NULL){printf("%5d",p->data);  p=p->next    ;}
    }
}

/*初始化队列*/
void initqueue(Queue *q)
{
 q->front=-1;
 q->rear=-1;
}

/*判断队列是否为空*/
int quempty(Queue *q)
{
if(  q->rear==q->front)
 return 1;
else
  return 0;
}

/*入队操作*/
void enqueue(Queue *q,int e)
{
 if(  (q->rear+1)%MAX==q->front)
 printf("queue is full\n");
 else
 {
  q->rear=(q->rear+1)%MAX;
  q->V[q->rear]=e;
 }
}

/*出队操作*/
int dequeue(Queue *q)
{
 int t;
 if(q->front==q->rear)
 {printf("queue is empty\n");return 0;}
 else
 {
  q->front=(q->front+1)%MAX;
  t=q->V[q->front];
  return t;
 }
}

/*深度优先遍历图,此部分代码要求手工输入*/
void dfsL(Lgraph G,int v)
{
Vnode *p;
printf("%d->",G[v].data);
visited[v]=1;
p=G[v].next;
while(p){v=p->data;if(visited[v]==0)dfsL(G,v);p=p->next;}
}

/*广度优先遍历图,此部分代码要求手工输入*/
void bfsL(Lgraph g,int v)
{
 int x;
 Vnode *p;
 Queue *q=(Queue *)malloc(sizeof(Queue));
 initqueue(q);
 printf("\n%d->",g[v].data);
 visited[v]=1;
 enqueue(q,v);
 while(!quempty(q))
 {
 x=dequeue(q);
 p=g[x].next;
 while(p){v=p->data;
 if(visited[v]==0)
 {
  printf("%d->",g[v].data);
  visited[v]=1;
  enqueue(q,v);
 }
 p=p->next;
 }
}
printf("\n");
}

第八章 查找

#include<stdio.h>
void bublesort(int a[10])
{
	int i,j,exchange,temp;
	for(i=0;i<10;i++)
	{
		exchange=0;
		for(j=9;j>=i;j--)
		if(a[j+1]<a[j]){
			temp=a[j+1];
			a[j+1]=a[j];
			a[j]=temp;
			exchange=1;
		}
		if(!exchange)
		break;
	}

	
	
}

 

//void insertsort(int a[10])
//
//{
//
//int i,j,temp;
//
//for(i=1;i<10;i++)
//
//{
//
// temp=a[i];j=i-1;
//
// while(a[j]>temp && j>=0)
//
// {a[j+1]=a[j];j--;}
//
//         a[j+1]=temp     ;
//
//    }
//
//  }

 

int binsearch(int a[10],int k)

{

int low,high,mid;

low=0;high=9;

while(low<=high)

{

 mid=    (low+high)/2      ;

 if(a[mid]==k) return mid;

 if(a[mid]>k)        high=mid-1       ;

 else     low=mid+1       ;

}

return -1;

}

 

 

int seqsearch(int a[10],int key)

{

 int i;

 for(i=0;i<10;i++)

 if(key==a[i]) return i;

 if(i==10) return -1;

}

 

main()

{

 int key,pos,i;

 int a[10]={34,87,23,15,32,46,67,62,28,30};

    for(i=0;i<10;i++)

  printf("%5d",a[i]);

   printf("\nplease enter the key which you want to find");

   scanf("%d",&key);

   pos=seqsearch(a,key);

    printf("the position of the %d is %d\n",key,pos);
	bublesort(a);
//  insertsort(a);

  printf("after sort:\n");

  for(i=0;i<10;i++)

  printf("%5d",a[i]);

  printf("\nplease enter the key which you want to find");

  scanf("%d",&key);

  pos=binsearch(a,key);

  printf("the position of the %d is %d\n",key,pos);

  getch();

}

第九章 排序

在这里插入图片描述

—插入排序

简单插入排序

#include<stdio.h>
#define n 9
typedef int KeyType;
typedef char OtherType;
typedef struct
{
	KeyType key;
	OtherType ch[2];
 }RecType;
 
typedef RecType SeqList[n+1];//数组可以容纳10个元素,下面只赋值了9个,R[9].key默认为0,R[9].ch默认为空 
//简单插入排序 
void InsertSort(SeqList R)
{
	int i,j;
	
	for(i=2;i<=n;i++)                    //从第2个元素遍历到第n个元素 
	{
		R[0]=R[i];                       //将第i个元素给哨兵R[0]
		for(j=i-1;R[0].key<R[j].key;j--) //若i元素前面一个元素大于哨兵R[0](即i元素) 
		R[j+1]=R[j];                     //则将i前面的元素i-1后移覆盖i元素 
		
		R[j+1]=R[0];                     //当i元素前面没有比i元素还小的元素时,将R[0]赋值给j+1个元素(即i前面的元素)
	}
	
}
int main(){

	SeqList R={{},{14,"A"},{6,"6"},{3,"3"},{5,"5"},{12,"Q"},{10,"10"},{11,"J"},{13,"K"}};//{}为哨兵 
	int i;
	InsertSort(R);
	for(i=2;i<=n;i++)//从2开始遍历,因为0位置为哨兵元素,1位置被哨兵元素覆盖为默认值0 
	printf("%3s(%d)",R[i].ch,R[i].key);	
}
输出:
>>  3(3)  5(5)  6(6) 10(10)  J(11)  Q(12)  K(13)  A(14)

希尔排序

—交换排序

冒泡排序
快速排序

—选择排序

直接选择排序
堆排序

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值