数据结构
【1】 数据:数据元素的集合; 数据元素:数据中的一项 数据项:描述数据元素的
结构:一种关系 数据结构:研究组成数据的数据元素之间的关系的学科 关系:
逻辑关系:线性关系(一对一),树形关系(层次关系)(一对多),网状关系(图状关系)(多对多),集合关系(离散关系)
存储关系:顺序存储,链式存储,索引存储,散列存储; 顺序存储:地址连续,查找方便。不方便频繁的插入删除,存储空间固定,容易产生碎片。 链式存储:插入删除方便,空间利用率高。地址不连续,查找相对不方便。 运算:创建数据模型 增删改查 展示数据。
算法:研究如何提高数据的处理效率 算法好坏:正确性,可读性,健壮性,时间效率高和存储量低 时间复杂度的计算:
1--将执行过程相加,常数部分变为1.
2--变量部分取最高次幂,其他的舍去
3--如果最高次幂不为1,那么他们的常数系数舍去 T(n)=O(n的平方)
【2】 线性表:
eg: sqlist.c 初识列表类型
#include<stdio.h>
#include<stdlib.h>//为了使用malloc申请堆空间添加的头文件
#define N 128
typedef int datatype;//为int起别名为datatype typedef struct {
datatype data[N];
int last;
}sq;
//typedef struct sqlist sq; sq *list_create();//创建sq类型变量在堆空间 void show(sq *);//显示sq类型数组中的数据
int list_insert(sq *,datatype );//向sq类型变量最后的位置添加datatype类型的数据内容 int list_insert1(sq *,datatype ,int );//向sq类型的列表空间指定位置添加datatype类型的数据内容 int list_delete(sq *,int);//删除
int list_search(sq *,datatype);//查找 int main()
{
sq *L; int i;
if( (L=list_create())==NULL)//判断L列表空间是否申请到了堆空间,没有的话提示出错
{
puts("malloc error"); return -1;
}
for(i=1;i<6;i++)//向L列表中赋值为1-5
{
if(list_insert(L,i)==-1)//判断赋值过程中是否出错 return -1;
}
show(L);//显示L列表中的数据内容 list_insert1(L,10,3);
show(L); list_delete(L,2); show(L);
list_repleas(L,13,1); show(L);
printf("%d\n",list_search(L,10));
return 0;
}
sq *list_create()
{
sq *L; if((L=malloc(sizeof(sq)))==NULL)//向堆空间申请地址,失败返回NULL并打印出错。
{
puts("malloc failed"); return NULL;
}
L->last=-1;//设置last的初值为-1,相当于指向数组data[],-1位,表示该数组没有内容。 return L;
}
int list_insert(sq *L,datatype value)
{
if(L->last==N-1)//如果赋值超过data[]数组的长度就打印出错信息,并返回-1
{
puts("list is full"); return -1;
}
L->data[L->last+1]=value; L->last++;
return 0;
}
int list_insert1(sq *L,datatype value,int i )
{
if(i<0||i>L->last) //判断插入的下标是否在last范围内如果不在就返回出错
{
puts("i error"); return -1;
}
int z;
for(z=L->last+1;z>i;z--)//从last的后一位开始直到给定的i所在的地址,
{
L->data[z]=L->data[z-1]; //将当前地址的内容等于前一个地址的内容。
}
L->data[i]=value; //将value的值赋值给i的位置 L->last++;
return 0;
}
void show(sq *L)
{
int i;
for(i=0;i<=L->last;i++)
printf("%d ",L->data[i]);//将data中的数据依次打印出来。 puts("");//打印一个换行
}
int list_delete(sq *L,int value)
{
if(L->==-1)//判断内容是否为空
{
puts("list is empty"); return -1;
}
if(value<0||value>L->last) //判断删除的指定下标是否存在如果不存在就提示该值为空。并结束函数。
{
puts("this is NULL"); return -1;
}
int i;
for(i=value;i<L->last;i++) //从指定的下标直到最后一个下标进行循环
{
L->data[i]=L->data[i+1];//将后一个值替换掉当前的值
}
L->last --; //最后的位置比原来小一相当于删除了其中一个 return 0;
}
int list_search(sq *L,datatype value)
{
int i;
for(i=0;i<=L->last;i++)
{
if(value==L->data[i]) //判断是否与当前的值相等
{
return i; //返回它的下标
}
}
return -1;
}
【3】
链式存储
%p 打印地址 eg:linklist.c
#include<stdio.h>
#include<stdlib.h>
typedef int datatype; typedef struct node{
datatype data; struct node *next;
}linknode;
linknode *list_create();//初始化头指针 int list_insert(linknode *H,datatype value);//在最后添加一个alue int list_insert1(linknode *H,datatype value,int pos);//在指定位子添加alue值 void list_show(linknode *);//打印所有的内容 int list_length(linknode *);//判断长度 int list_delete(linknode *,datatype );//删除指定内容 int list_recever(linknode *);//实现反转
int main()
{
linknode *H; int i;
if((H=list_create())==NULL)//判断是否申请到来空间
{
puts("create error"); return -1;
}
for(i=0;i<6;i++)
{
list_insert(H,i);
}
list_show(H); printf("%d\n",list_length(H)); list_delete(H,3); list_show(H); list_insert1(H,10,3); list_show(H);
list_recever(H); list_show(H); return 0;
}
linknode *list_create()
{
linknode *H; if((H= wo(sizeof(linknode)))==NULL)//通过malloc申请堆空间
{
puts("malloc failed"); return NULL;
}
H->next=NULL;//让next开锁指向空 return H;
}
int list_insert(linknode *H,datatype value)
{
linknode *p; if((p=malloc(sizeof(linknode)))==NULL)//判断是否申请到来空间
{
puts("node malloc failed "); return -1;
}
p->data=value;//将value的值赋值给p的data p->next =H->next;//p的next值代替H的next H->next=p;//H的next指向p的地址
return 0;
}
void list_show(linknode *H)
{
linknode *p; p=H->next;
while(p!=NULL)//如果p现在的空间不是NULL就循环将data的值打印出来
{
printf("%d ",p->data); p=p->next;
}
puts("");//换行
}
int list_length(linknode *H)
{
int i=0;//用于计算H的长度 while(H)//如果H的值不算空就进行循环
{
H=H->next; i++;
}
return i;
}
int list_delete(linknode *H,datatype value)
{
if(H->next==NULL)//判断数组是否为空
{
puts("list is empty"); return -1;
}
linknode *p;//p代表当前位子 linknode *p1;//p1代表下一个位子 p=H->next;//设p的初值
while(p)//相当与p!=NULL 也就是不到最后一个
{ p1=p->next;
if(p1->data==value)//如果p1的data值是否是要删除的值 break;
p=p->next;//p的值向下查找
}
p->next=p1->next;//让p的next值直接指向p1的next值相当与删除来p1 free(p1);//将p1的空间释放
p1=NULL;
return 0;
}
int list_insert1(linknode *H,datatype value,int pos)
{
linknode *p;//要插入的元素 linknode *q;//要插入的位子 q=H->next;
if((p=malloc(sizeof(linknode)))==NULL)//申请一个堆栈空间
{
puts("node malloc failed"); return -1;
}
while(--pos)//循环找到要插入的位子 q=q->next;
p->data=value;//将value的值赋值给p
p->next=q->next;//让p指向当前位子指向的下一个位子 q->next=p;//q指向p的位子
return 0;
}
int list_recever(linknode *H)//使用头插法
{
linknode *p,*q=p;//定义两个指针变量,p代表下一个位子,p代表当前位子 p=H->next;
H->next=NULL; while(q!=NULL)//一直循环到结束
{
q=p->next;//将q的值向下走
p->next=H->next;//将p前提到最前边 H->next=p;
p=q;//用p代表当前位子
}
return 0;
}
【4】单项循环链表
H->next=H;其余同链表
【5】双项循环链表 拥有向前的指针
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node{ datatype data; struct node *prior; struct node *next;
}linknode;
int list_lenght(linknode*); int list_insert(linknode*,datatype);
int list_insert2(linknode*,datatype,int); int list_delete(linknode*,datatype); int list_replace(linknode *,datatype,datatype); int list_search(linknode*,datatype);
void list_show(linknode *); linknode *list_create();
int main(int argc, const char *argv[])
{
linknode * H = NULL; int i,a[] = {1,2,3,4,5,6,7,8,9};
if((H = list_create()) == NULL)
return -1;
for(i = 0;i < 9;i++) list_insert(H,a[i]);
list_show(H);
list_delete(H,4); list_show(H); list_replace(H,3,10); list_show(H); list_search(H,5); list_insert2(H,20,5); list_show(H); printf("%d\n",list_lenght(H)); return 0;
return 0;
}
linknode *list_create()
{
linknode *H;
if((H = malloc(sizeof(linknode))) == NULL)
{
puts("malloc failed\n"); return NULL;
}
H->prior = NULL; H->next = NULL;
return H;
}
int list_lenght(linknode*H)
{
int n = 0; linknode *p = H->next; while(p)
{
p = p->next; n++;
}
return n;
}
int list_insert2(linknode*H,datatype value,int pos)
{
int i = 0; linknode *p = H,*q;
while(i < pos && p != NULL)
{
p = p->next; i++;
}
if(p == NULL)
{
puts("pos error"); return -1;
}
if((q = malloc(sizeof(linknode))) == NULL)
{
puts("malloc failed\n"); return -1;
}
q->data = value;
q->prior = p;
q->next = p->next; p->next->prior = q; p->next = q;
return 0;
}
int list_insert(linknode* H,datatype value)
{
linknode *p; if((p = malloc(sizeof(linknode))) == NULL)
{
puts("malloc failed"); return -1;
}
p->data = value;
p->next = H->next; p->prior = H;
H->next = p;
return 0;
}
int list_delete(linknode* H,datatype value)
{
int i; linknode *p = H,*q;
if(H->next == NULL)
{
puts("list is empty\n"); return -1;
}
while(p)
{
q = p->next;
if(q->data == value)
{
p->next = q->next; q->next->prior = p; free(q);
q = NULL;
return 0;
}
p = p->next;
}
return -1;
}
int list_replace(linknode *H,datatype value1,datatype value2)
{
linknode * p = H->next; while(p)
{
if(p->data == value1)
{
p->data = value2; return 0;
}
p = p->next;
}
return -1;
}
int list_search(linknode*H,datatype value)
{
linknode *p = H->next; while(p)
{
if(p->data == value) return value;
p = p->next;
}
return -1;
}
void list_show(linknode *H)
{
linknode *p = H->next;
while(p)
{
printf("%d ",p->data); p = p->next;
}
putchar(10);
}
【5】
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node{ datatype data; struct node * next;
}linknode;
linknode * list_create(); int list_insert(linknode*H,datatype value,int pos); void list_show(linknode*); void jose(linknode *H,int k,int m);
int main(int argc, const char *argv[])
{
linknode *H; if((H = list_create()) == NULL) return -1;
list_show(H);
jose(H,3,4); return 0;
}
linknode * list_create()
{
int i; linknode * H;
if((H = malloc(sizeof(linknode))) == NULL)
{
puts("malloc failed"); return NULL;
}
H->data = 1; H->next = H;
for(i = 2;i <= 8;i++) list_insert(H,i,i-2); return H;
}
int list_insert(linknode*H,datatype value,int pos)
{
int i = 0; linknode *p = H,*q;
while(i < pos)
{
p = p->next; i++;
}
if((q = malloc(sizeof(linknode))) == NULL)
{
puts("malloc failed\n"); return -1;
}
q->data = value;
q->next = p->next; p->next = q; return 0;
}
void list_show(linknode *H)
{
linknode *p = H; do
{
printf("%d ",p->data); p = p->next;
}while(p != H);
putchar(10);
}
void jose(linknode *H,int k,int m)
{
int i; linknode *p = H,*q; while(p->data != k) p = p->next;
while(p->next != p)
{
for(i = 0;i < m- 2;i++ )
p = p->next;
q = p->next;
p->next = q->next; printf("%d ",q->data); free(q);
q = NULL;
p = p->next;
}
printf("%d\n",p->data); free(p);
p = NULL;
}
【6】栈和队列 栈:是限制在一端进行插入操作和删除操作的线性表(俗称堆栈)允许操作的一端称为“栈顶”另一端称为“栈底”,当栈中没有元素时 称为“空栈”:特点:后进先出(LIFO)。
sqstack.c
#include <stdio.h>
#include <stdlib.h>
#define N 128 typedef int datatype;
typedef struct{ datatype data[N]; int top;
}sqstack;
sqstack * stack_create();//创建栈 int push(sqstack *,datatype);//入栈 datatype pop(sqstack *);//出栈 int empty(sqstack *);//是否为空 int full(sqstack *);//是否为满
int main()
{
sqstack * s; if((s = stack_create()) == NULL)
{
puts("create error"); return -1;
}
push(s,10);
push(s,20);
push(s,30);
push(s,40);
push(s,50);
push(s,60);
while(!empty(s)) printf("%d ",pop(s));
putchar(10); return 0;
}
sqstack * stack_create()
{
sqstack *s; if((s = malloc(sizeof(sqstack))) == NULL)
{
puts("malloc failed"); return NULL;
}
s->top = -1; return s;
}
int push(sqstack *s,datatype value)
{
if(full(s) == 1)
{
puts("stack is full"); return -1;
}
s->data[s->top + 1] = value; s->top++;
return 0;
}
datatype pop(sqstack *s)
{
if(empty(s) == 1)
{
puts("stack empty"); return -1;
}
s->top--;
return s->data[s->top + 1];
}
//1 ---empty 0----not empty int empty(sqstack *s)
{
return (s->top == -1) ? 1 : 0;
}
//1 ---full 0----not full int full(sqstack *s)
{
return (s->top == N- 1) ? 1 : 0;
}