数据结构

来源:互联网 发布:起点中文网数据 编辑:程序博客网 时间:2024/06/03 15:40

/*==============线性表的顺序存储结================*/

#define MAXSIZE 20

typedef int ElemType;

typedef struct
{
ElemType data[MAXSIZE];
int length;
}SqList;


/*==获取元素操作==*/
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

============以上为宏定义============
typedef int Status;
Status GetElem(SqList L,int i,ElemType *e)
{
if(L.length == 0 || i>L.length || i<1)
return ERROR;
*e = L.length[i-1];
return OK;
}

typedef struct
{
ElemType data[MAXSIZE];
int length;
}SqList;


/*==获取元素操作==*/
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
Status GetElem(SqList L,int i,ElemType *e)
{
if(L.length == 0 || i>L.length || i<1)
return ERROR;
*e = L.length[i-1];
return OK;
}


/*元素插入操作*/
/*算法思路:
1.如果插入位置不合理,抛出异常;
2.如果线性表长度大于等于数组长度,则抛出异常或动态增加容量
3.从最后一个元素开始向前遍历到第i个位置,分别将他们都向后移动一个位置
4.将要插入元素填入位置i处
5.表长加1*/

Status ListInsert(SqList *L,int i,ElemType e)
{
int k;
if (L->length == MAXSIZE)
return ERROR;
if(i < 1 || i > L->length + 1)
return ERROR;
if(i <= L->length)
{
for(k=L->length-1;k>=i-1;k--)
L->data[k+1] = L->data[k];
}
L->data[i-1] = e;
L->length++;
return OK;
}



/*元素删除操作*/
/*算法思路:
1.如果删除位置不合适,抛出异常
2.取出删除元素
3.从删除位置元素开始到遍历最后一个元素位置,分别将他们都向前移动一个位置
4.表长减1*/


Status ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if(L->length == 0)
return ERROR;
if(i <1 || i > L->length)
return ERROR;
*e = L->length[i-1];
if(i < L->length)
{
for(k=i,k<L->length;k++)
L->data[k-1] = L->length[k];
}
L->length--;
return OK;

}



//可以快速的进行读取数据O(1),但对于删除和插入数据需要复杂操作O(n)


/*======================================================*/
/*=================线性表的链式存储结构=================*/
/*======================================================*/

/*单链表的存储结构*/

typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;



/*单链表的读取算法
1.声明一个指针P指向链表的第一个节点,初始化j从1 开始;
2.当j<i时,就遍历链表,让p的指针向后移动一位,j累加1;
3.若当链表末尾p为空时,则说明第i个节点不存在;
4.否则查找成功,返回节点p的数据*/

Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while( p && j<i)                  //开始指向第一个节点,因此P指第I个位置的元素,具体可以将p的指向和J的值对应写出来
{ //需要判断第I个节点存在
p = p->next;
++j;
}
if(!p || j>i)
return ERROR;
*e = p->data;
return OK;
}

/*单链表的插入
1.声明一指针指向链表L头结点,初始化J从1开始;
2.当j<i时,就遍历链表,让p的指针向后移动一位,j累加1;
3.若链表为空则说明第i个节点不存在;
4.否则查找成功,在系统中生成一个空节点S;
5.将数据元素e赋值给S->DATA;
6.单链表插入语句:s->next = p ->next; p->next = s
7.返回成功*/

Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s;
p = *L;
j = 1;
while(p && j<i)                  //遍历寻找第i-1个节点
//需要判断第i-1个节点存在才可以插入
{
p = p->next;
++j;
}
if(!p || j > i)
return ERROR;
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}

/*单链表的删除
1.声明一个指针P指向链表表头指针
2.当J<i时,就遍历链表,让p的指针向后移动,不断指向下一个节点,j累加1
3.若到链表末尾P为空,则说明第I个节点不存在
4.否则查找成,将删除的节点p->next赋值给q
5.单链表的删除标准语句p->next = q->next;
6.将q节点中的数据赋值给E,作为返回
7.释放Q节点
8.返回成功*/

Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p = *L;
j = 1;
while(p->next && j<i)//判断第i个节点存在才可以删除
{
p = p->next;
++j;
}
if(!(p->next) || j > i)
return ERROR;
q = p->next;
p->next = q ->next;
*e = q->data;
free(q);
return OK;

}

*单链表的整表创建
2.初始化一空链表L
3.让L的头结点的指针指向NULL,即建立一个带头结点的单链表
4.循环
生成一新节点赋值给P
随机生成一个数字赋值给p->data
将p插入到头结点与前一节点之间*/

1.声明一指针P和计数器变量I
//头插法
void CreateListHead(LinkList *L,int n)
{
LinkList p;
int i;
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
for(i=0;i<n;i++)
{
p = (LinkList)malloc(sizeof(Node));//返回的是一个指针
p->data = rand()%100 + 1;
p->next = (*L)->next;
(*L)->next = p;
}
}
//尾插法
void CreateListHead(LinkList *L,int n)
{
LinkList p,r;
int i;
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
r = *L;
for(i=0;i<n;i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100 + 1;
r->next = p;
r = p;
}
r->next = NULL;
}



/*单链表的整表删除
1.声明一个节点p和q
2.将第一个节点赋值给p
3.循环
将下一个节点赋值给Q
释放p
将p赋值给p*/

Status ClearList(LinkList *L)
{
LinkList p,q;
p = (*L)->next;
while(p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}


/*循环列表:将头指针换成尾指针,尾部指向头指针,而不是空指针。
下面演示将两个循环链表连接起来*/


p = rearA->next;
 q = rearB->next;
rearB->next = p;
free(q);

//3 5 步实际上是释放B的头指针,也可以直接写成free(rearB->next)

/*双向链表*/

/*双向链表的结构*/



typedef struct DulNode
{
ElemType data;
struct DulNode *prior;
struct DulNode *next;
}DulNode, *DuLinkList;


/*栈的结构定义*/
typedef int SElemType;
typedef struct
{
SElemType data[MAXSIZE];
int top;
}SqStack;


//进栈操作
Status Push(SqStack *S,SElemType e)
{
if(S->top == MAXSIZE-1)
{
return ERROR;
}
S->top++;
S->data[S->top] = e;
return OK;
}
//出栈操作
Status Pop(SqStack *S,SElemType *e)
{
if(S->top == -1)
{
return ERROR;
}
*e = S->data[S->top];
S->top--;
return OK;
}



/*两栈共享空间结构*/

typedef struct
{
SElemType data[MAXSIZE];
int top1;
int top2;
}SqDoubleStack;



//进栈操作

Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
if(S->top1+1 == S->top2)
{
return ERROR;
}
if(stackNumber == 1)
{
S->data[++S->top1] = e;
}
else if(stackNumber == 2)
{
S->data[--S->top2] = e;
}
return OK;
}


//出栈操作



Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
if(stackNumber == 1)
{
if(S->top1 == -1)
return ERROR;
*e = S->data[S->top1--];
}
else if(stackNumber == 2)
{
if(S->top2 == MAXSIZE)
return ERROR;
*e = S->data[S->top2++];
}
return OK;

}

/*栈的链式存储结构*/
//链栈的结构



typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;


typedef struct LinkStack
{
LinkStackPtr top;
int count;
}LinkStack;


/*进栈操作*/

Status Push(LinkStack *S,SElemType e)
{
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
s->data = e;
s->next = S->top;
S->top = s;
S->count++;
return OK;
}

/*出栈操作*/

Status Pop(LinkStack *S,SElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
return ERROR;
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
S->count--;
return OK;
}

/*队列的顺序存储结构*/


/*队列顺序存储结构代码*/

typedef int QElemType;
typedef struct
{
QElemType data[MAXSIZE];
int front;
int rear;
}SqQueue;



//循环队列的初始化

Status InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}

//求队列长度

Status QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}

//入队列操作

Status EnQueue(SqQueue *Q,QElemType e)
{
if((Q->rear+1)%MAXSIZE == Q->front)
return ERROR;
Q->data[Q->rear] = e;
Q->rear = (Q->rear+1)%MAXSIZE;
return OK;
}

//出队列操作

Status DeQueue(SqQueue *Q,QElemType *e)
{
if(Q->rear == Q->front)
return ERROR;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAXSIZE;
return OK;
}



//队列的链式结构

typedef int QElemType;
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear;
}LinkQueue;

//入队操作

Status EnQueue(LinkQueue *Q,QElemType e)
{
QueuePtr s =(QueuePtr)malloc(sizeof(QNode));
if(!s)
exit(OVERFLOW);
s->data = e;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
return OK;
}

//出队操作

Status DeQueue(LinkQueue *Q,QElemType *e)
{
QueuePtr p;
if(Q->front == Q->rear)
return ERROR;
p = Q->front->next;
*e = P->data;
Q->front->next = p->next;
if(Q->rear == p)
Q->rear = Q->front;
free(p);
return OK;
}



/*串:由零个或多个字符组成的有限序列,又名叫字符串*/
//操作index的算法
/*T为非空串,若主串S中第pos个字符之后存在与T相等的子串*/
/*则返回第一个在这样的子串在S中的位置*/
int Index(String S,String T,int pos)
{
int n,m,i;
String sub;
if(pos > 0)
{
n = Strlength(S);
m = Strlength(T);
i = pos;
while(i <= n-m+1)
{
SubString(sub,S,i,m);
if(StrCompare(sub,T)!=0)
++i;
else
return i;
}
}
return 0;
}


//低效的模式匹配问题
int Index(String S,String T,int pos)
{
int i=pos;
int j=1;
while(i<=S[0]&&j<=T[0])
{
if(S[i] == T[j])
{
++i;
++j;
}
else
{
i = i - j + 2;
j = 1;
}
}
if(j>T[0])
return i-T[0];
else
return 0;
}


//KMP模式匹配算法

/*通过计算返回子串T的next数组*/
void get_next(String T,int *next)
{
int i,j;
i=1;
j=0;
next[1] = 0;
while(i <= T[0])
{
if(j==0 || T[i] == T[j])
{
i++;
j++;
next[i] = j;
}
else 
j = next[j];
}
}


int Index_KMP(String S,String T,int pos)
{
int i = pos;
int j = 1;
int next[255];
get_next(T,next);
while(i <= S[0] && j <= T[0])
{
if(j==0 || S[i] == T[j])
{
++i;
++j;
}
else
j = next[j];
}
if(j>T[0])
return i-T[0];
else
return 0;
}


//求next数组还是有点缺陷的,因此设计另一个数组nextval,对算法进行改进


void get_nextval(String T,int *nextval)
{
int i,j;
i = 1;
j = 0;
nextval[1] = 0;
while(i <= T[0])
{
if(j == 0 || T[i] == T[j])
{
i++;
j++;
if(T[i]!=T[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}


//树的概念及基本操作



/*双亲表示法结构定义*/
#define MAX_TREE_SIZE 100
typedef int TElemType;
typedef struct PTNode
{
TElemType data;
int parent;
}PTNode;
typedef struct{
PTNode nodes[MAX_TREE_SIZE];
int r,n;
}PTree;


/*孩子表示法结构定义*/
#define MAX_TREE_SIZE 100
typedef struct CTNode               //孩子节点
{
int child;
struct CTNode *next;
}*ChildPtr;


typedef struct
{
TElemType data;
ChildPtr firstchild;
}CTBox;


typedef struct
{
CTBox nodes[MAX_TREE_SIZE];
int r,n;
}


/*树的孩子兄弟表示法*/
typedef struct CSNode
{
TElemType data;
struct CSNode *firstchild,*rightsib;
}CSNode,*CSTree;