数据结构线性表,栈,队列的基本操作

顺序表的基本操作

定义顺序表

typedef int ElemType;
typedef struct{ // 线性表中共有length个元素,是data[0]——data[length-1]
int data[MAXSIZE];
int length;
}SqList;

初始化

int initList(SqList *L)
{
L->length=0;
return 1;
}

打印顺序表

int printList(SqList L)
{
if(L.length==0)
{ printf(“链表为空\n”);
return 0;
}
int i;
for(i=0;i<L.length;i++){
printf(“data[%d] = %d\n”,i,L.data[i]);
}
printf("\n");
return 1;
}

获取顺序表长度

int getlength(SqList L){
return L.length;
}

创建一个顺序表,每个元素随机赋值

int createList(SqList *L,int length){
srand(time(0));
int i;
for(i=0;i<length;i++){
L->data[i]=rand()%100;
L->length++;
}
return 1;
}

在指定位置处插入一个新的元素

int insertList(SqList *L, int pos,ElemType elem){
int i;
if(pos<1 || pos>L->length)
{
printf(“插入的位置有误,无法插入数据\n”);
return 0;
}
for (i=L->length-1;i>=pos-1;i–)
{
L->data[i+1]=L->data[i];
}
L->data[pos-1] = elem;
L->length++;
return 1;
}

获取顺序表中指定位置处的元素值

int getElem(SqList L, int pos, ElemType *e){
if(pos<1 || pos>L.length)
{
printf(“查找位置有错误,无法获取指定位置的数据\n”);
*e=99999999;
return 0;
}
*e = L.data[pos-1];
return 1;
}

查找在线性表中是否含有指定元素

int locateElem(SqList L, ElemType e){
int i;
for(i=0;i<L.length;i++)
{
//printf(“在%d层循环…\n”,i);
if(L.data[i] == e)
{
printf(“在pos[%d]位置处,查找到了元素elem:%d\n”,i+1,e);
return 1;
}
}
return 0;
}

删除顺序表中指定位置处的元素

int deleteList(SqList *L, int pos,ElemType *elem){
int i;
if(pos<1 || pos>L->length)
{
printf(“删除的位置有误,无法从该位置删除数据\n”);
*elem=99999999;
return 0;
}
*elem = L->data[pos-1];
for(i=pos;ilength;i++){
L->data[i-1]=L->data[i];
}
L->length --;
return 1;
}

清空一个顺序表,将顺序表的length置为0;

int clearList(SqList L,SqList *pL){
printf(“In clearList function: %d\n”,&L);
printf(“In clearList function: %d\n”,pL);
L.length=0;
pL->length=0;
return 1;
}

说明

1、在上面顺序表操作函数中,有的入参是SqList类型的,有的是SqList*类型的,两者是有区别的,通过clearList()函数进行说明;
2、入参有两种类型,这是为了测试在函数内部,处理的顺序表在内存中的位置是什么,在函数内部,会把顺序表的位置以%d的方式打印出来;同时在调用函数之前,会把传入的入参顺序表L的地址打印出来;

通过测试发现,如果入参为SqList L,在函数内部地址同外部的顺序表L地址不相同,如果入参为SqList *pL,在函数内部地址同外部的顺序表L地址相同;当入参为SqList L时,执行L.length=0;无效,根本没有将顺序表的唱的长度置为0;
3、综上所述,如果要修改顺序表中的值(包括长度,以及各个元素的值),比如创建顺序表、插入元素、删除元素等等操作,是对顺序表内的数据有改动的,就要传入SqList *类型的入参,否则达不到修改的目的;【这其实就是函数的值传递和地址传递】

单链表的基本操作

定义单链表

typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node * next;
}Node;
typedef struct Node* linkList;

初始化

int initList(linkList *L)
{
(*L) = (linkList)malloc(sizeof(Node));
(*L)->next = NULL;
printf(“链表初始化成功\n”);
return 1;
}

创建一个单链表

int createListHead(linkList *L,int n) {
linkList p;
int i = 0;
srand((int)time(0));
for (i = 0; i < n; i++)
{
p= (linkList)malloc(sizeof(Node));
p->data = rand() % 100;
printf(“testing:Node[%d]=%d\n”,i+1,p->data);
p->next = (*L)->next;
(*L)->next = p;
}
printf(“链表(头插法)创建成功\n”);
return 1;
}
int createListTail(linkList *L, int n) {
linkList p, temp;
temp = (*L);
int i;
srand((int)time(0));
for (i = 0; i < n;i++) {
p = (linkList)malloc(sizeof(Node));
p->data = rand() % 100;
printf(“testing:Node[%d]=%d\n”, i + 1, p->data);
p->next = NULL;
temp->next = p;
temp = p;
}
printf(“链表(尾插法)创建成功\n”);
return 1;
}

获取链表的长度

int getlength(linkList *L) {
linkList p;
int length=0;
p = (*L)->next;//p指向第一个节点;
while § {
length++;
p = p->next;
}
return length;
}

打印整个链表

int printList(linkList *L) {
linkList p;
int i = 0;
p = (*L)->next;//p指向第一个节点;
printf("-----------打印整个链表-----------\n");
if (p==NULL) {
printf(“这是一个空链表.\n”);
}
while § {
i++;
printf(“第%d个节点的数据data为=%d\n”,i,p->data);
p = p->next;
}
return 1;
}

获取指定位置处的节点元素

int getElem(linkList *L, int i, ElemType *getdata) {
linkList p;
p = (*L)->next;
if (p == NULL)
{
printf(“链表为空,请创建一个链表\n”);
*getdata = -1;
return 0;
}
if (i < 1)
{
printf(“您所查询的节点%d,应该大于0,请重新输入查询\n”,i);
*getdata = -1;
return 0;
}
int j = 1;
while (p&&j<i) {
j++;
p = p->next;
}
if (p == NULL)
{
printf(“您所查询的节点%d,已经超出了数组的长度\n”,i);
*getdata = -1;
return 0;
}
*getdata = p->data;
printf(“查询成功!\n”, i);
return 1;
}

插入节点

int insertList(linkList *L, int i, ElemType data)
{
linkList p;
linkList insNode;
p = (*L);
int j=0;
// 链表为空,在第1个位置插入一个新的节点;
if (p ->next == NULL) {
printf(“链表为空,默认在第一个位置插入一个节点.\n”);
insNode = (linkList)malloc(sizeof(Node));
insNode->data = data;
insNode->next = p->next;
p->next = insNode;
printf(“节点插入成功.\n”);
return 1;
}
// 链表非空的情况下,可以在i=1~length的位置插入节点,如果超过了链表的长度,就会提示错误;
// 其实如果在length+1的位置处插入一个新节点,就相当于在尾部追加一个节点,在本函数中会报错,可以单独实现一个函数;
while(p && j<i-1)
{
j++;
p = p->next;
//printf(“j=%d\tp->data=%d\n”, j, p->data);
}
if (p->next==NULL) {
printf(“您要插入的位置,超过了链表的长度 %d,请重新操作!\n”,j);
return 0;
}
insNode = (linkList)malloc(sizeof(Node));
insNode->data = data;
insNode->next = p->next;
p->next = insNode;
printf(“节点插入成功\n”);
return 1;
}

追加节点

int insertListTail(linkList *L, ElemType data)
{
linkList temp;
linkList p=(*L);
while§ {
temp = p;
p = p->next;
}
p = (linkList)malloc(sizeof(Node));
p->data = data;
p->next = NULL;
temp->next = p;
printf(“节点插入成功\n”);
return 1;
}

删除节点

int deleteList(linkList *L, int i, ElemType *data)
{
linkList p,pnext;
int j = 0;
p = (*L);
if (p->next == NULL) {
printf(“链表为空,无法删除指定节点.\n”);
*data = -1;
return 0;
}
while (p->next && j<i-1) {
j++;
p = p->next;
//printf(“j=%d\t p->data=%d\n”,j,p->data);
}//条件最多定位到最后一个节点;
if ( p->next == NULL) {
printf(“您要删除的节点,超过了链表的长度 %d,请重新操作!\n”, j);
*data = -1;
return 0;
}
pnext = p->next;
p->next = pnext->next;
*data = pnext->data;
free(pnext);
printf(“节点删除成功\n”);
return 1;
}

删除整个链表

int clearList(linkList *L) {
linkList p, temp;
p = (*L)->next;//p指向第一个节点
while § {
temp = p;
p = p->next;
free(temp);
}
(*L)->next = NULL;
printf(“整个链表已经clear.\n”);
return 1;
}

顺序栈的基本操作

定义

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

#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define QUEUESIZE 10 //栈长度10

typedef int Status;
typedef int QElemtype;

typedef struct QNode{
QElemtype *base;
int top;
}SqQueue;

初始化

void InitQueue(SqQueue Q)
{
Q->base=(QElemtype
)malloc(sizeof(QElemtype)*QUEUESIZE);
assert(Q->base!=NULL);
Q->top=0;
}

入栈

Status EnQueue(SqQueue *Q,QElemtype e)
{
if(Q->top==QUEUESIZE)
{
return ERROR;
}
Q->base[Q->top]=e;
Q->top++;
return OK;
}

判断栈是否为空

Status QueueEmpty(SqQueue *Q)
{
if(Q->top==0)
{
return TRUE;
}
return FALSE;
}

求栈长

Status QueueLength(SqQueue Q)
{
return Q.top;
}

获取栈顶元素

Status GetHead(SqQueue *Q,QElemtype *e)
{
if(Q->top==0)
{
return ERROR;
}
*e=Q->base[Q->top];
return OK;
}

销毁队栈

void DestoryQueue(SqQueue *Q)
{
if(Q->base) //栈Q存在
{
free(Q->base);
}
Q->base=NULL;
Q->top=0;
}

清空栈

void ClearQueue(SqQueue *Q)
{
Q->top=0;
}

出栈

Status DeQueue(SqQueue *Q,QElemtype *e)
{
if(Q->top==0)
{
return ERROR;
}
*e=Q->base[Q->top-1];
Q->top–;
return OK;
}

遍历栈

void QueueTraverse(SqQueue Q)
{
int i=0;
while(i!=Q.top)
{
printf("%d\t",Q.base[i]);
i++;
}
printf("\n");
}

测试

int main()
{
QElemtype i,e,d;
SqQueue Q;
InitQueue(&Q);
printf(“请输入栈列的%d个元素:\n”,QUEUESIZE);
for(i=0;i<QUEUESIZE;i++)
{
scanf("%d",&d);
EnQueue(&Q,d);
}
printf(“栈的元素为:”);
QueueTraverse(Q);
printf(“栈长度为:%d\n”,QueueLength(Q));
int k=QueueLength(Q);
printf(“连续%d次出栈入栈:\n”,k/2);
for(i=0;i<k/2;i++)
{
DeQueue(&Q,&e);
printf(“出栈的元素是:%d,请输入入栈的元素:”,e);
scanf("%d",&d);
EnQueue(&Q,d);
}
printf(“新的栈元素为:\n”);
QueueTraverse(Q);
int n=GetHead(&Q,&e);
if(n)printf(“栈顶元素为:%d\n”,e);
else {
printf(“栈空!\n”); return -1;
}
ClearQueue(&Q);
DestoryQueue(&Q);
return 0;
}

链栈的基本操作

定义

typedef int ElemType;
typedef struct linknode
{
ElemType data;
struct linknode *next;
}LiStack;

初始化

void InitStack(LiStack* S)
{
S=(LiStack*)malloc(sizeof(LiStack));
S->next=NULL;
}

销毁链栈

void DestroyStack(LiStack* s)
{
LiStack *p=s->next,*q=s;
while(p!=NULL)
{
free(q);
q=p;
p=p->next;
}
free§;
}

判断链栈是否为空

int StackEmpty(LiStack* s)
{
if(s->next==NULL)
return 0;
else
return 1;
}

进栈

void Push(LiStack* s,ElemType e)
{
LiStack p;
p=(LiStack
)malloc(sizeof(LiStack));
p->data=e;
p->next=s->next;
s->next=p;
}

出栈

int Pop(LiStack* s,ElemType e)
{
LiStack *p=s->next;
if(s->next!=NULL)
return 0;
else
{
e=p->data;
s->next=p->next;
free§;
return 1;
}
}

得到栈顶元素

int GetTop(LiStack* s,ElemType e)
{
LiStack *p=s->next;
if(s->next==NULL)
return 0;
e=p->data;
return 1;
}

输出链栈元素

void PrintStack(LiStack* s)
{
LiStack *p=s->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}

顺序队列的基本操作

定义

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define QUEUESIZE 10 //队列长度10,9元素为满
typedef int Status;
typedef int QElemtype;
typedef struct QNode{
QElemtype *base;
int front;
int rear;
}SqQueue;

初始化

void InitQueue(SqQueue Q)
{
Q->base=(QElemtype
)malloc(sizeof(QElemtype)*QUEUESIZE);
assert(Q->base!=NULL);
Q->front=0;
Q->rear=0;
}

入队

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

判断队列是否为空

Status QueueEmpty(SqQueue *Q)
{
if(Q->front==Q->rear)
{
return TRUE;
}
return FALSE;
}

求队长

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

获取队头元素

Status GetHead(SqQueue *Q,QElemtype *e)
{
if(Q->front==Q->rear)
{
return ERROR;
}
*e=Q->base[Q->front];
return OK;
}

销毁队列

void DestoryQueue(SqQueue *Q)
{
if(Q->base) //队列Q存在
{
free(Q->base);
}
Q->base=NULL;
Q->front=Q->rear=0;
}

清空队列

void ClearQueue(SqQueue *Q)
{
Q->front=Q->rear=0;
}

出队

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

遍历队列

void QueueTraverse(SqQueue Q)
{
int i=Q.front;
while(i!=Q.rear)
{
printf("%d\t",Q.base[i]);
i=(i+1)%QUEUESIZE;
}
printf("\n");
}

测试

int main()
{
QElemtype i,e,d;
SqQueue Q;
InitQueue(&Q);
printf(“请输入队列的%d个元素:\n”,QUEUESIZE-1);
for(i=0;i<QUEUESIZE-1;i++)
{
scanf("%d",&d);
EnQueue(&Q,d);
}
printf(“队列的元素为:”);
QueueTraverse(Q);
printf(“队列长度为:%d\n”,QueueLength(Q));
int k=QueueLength(Q);
printf(“连续%d次由对头删除元素,队尾插入元素:\n”,k/2);
for(i=0;i<k/2;i++)
{
DeQueue(&Q,&e);
printf(“删除的队列的元素是:%d,请输入插入的元素:”,e);
scanf("%d",&d);
EnQueue(&Q,d);
}
printf(“新的队列元素为:\n”);
QueueTraverse(Q);
int n=GetHead(&Q,&e);
if(n)printf(“队头元素为:%d\n”,e);
else {
printf(“队空!\n”); return -1;
}
ClearQueue(&Q);
printf(“清空队列后队列是否为空:%d\t(1:为空 ,0:不为空)\n”,QueueEmpty(&Q));
DestoryQueue(&Q);
printf(“销毁队列后:\nQ.base=%u\tQ.front=%d\tQ.rear=%d\t\n”,Q.base,Q.front,Q.rear);
return 0;
}

链队列的基本操作

定义

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define OK 1
int yes=0;
typedef struct node
{
char data;
struct node *next;
}node,*queueptr;
typedef struct
{
queueptr front;
queueptr rear;
}linkqueue;

初始化

void initqueue(linkqueue q)
{
q->front=q->rear=(node
)malloc(sizeof(node));
if(!(q->front))
exit(1);
q->front->next=NULL;
}

入队

void enqueue(linkqueue *q,char e)
{
queueptr p;
p=(queueptr)malloc(sizeof(node));
if(!p)exit(1);
p->data=e;
p->next=0;
q->rear->next=p;
q->rear=p;
}

创建一个长度由自己决定的队列并初始化

void creatqueue(linkqueue *q)
{
int i,length;
int num;
queueptr p;
printf(“请输入队列长度:\n”);
scanf("%d",&length);
printf(“请输入队列的元素:\n”);
for(i=0;i<length;i++)
{
p=(queueptr)malloc(sizeof(node));
if(!p)
exit(1);
scanf("%d",&num);
p->data=num;
p->next=0;
q->rear->next=p;
q->rear=p;
}
yes=1;
}

销毁队列

void destroyqueue(linkqueue *q)
 {
  if(!q)
 {
  printf(“链队列已经是空队列!\n”);
  exit(1);
  }
  while(q->front)
  {
  q->rear=q->front->next;
  free((q->front));
  q->front=q->rear;
  if(!q->rear)
  free(q->rear);
  }
  free(q->front);
  }

遍历队列

 void disqueue(linkqueue *q)
 {
     node *r=q->front->next;
     printf("此时的链队列输出:\n");
     while(r)
     {
         printf("%d  ",r->data);
         r=r->next;
     }
     printf("\n");
 }

求队列长度

 void lenqueue(linkqueue *q)
 {
     node *r=q->front->next;
     int s=0;
     printf("此时的链队列长度为:\n");
     while(r)
     {
         r=r->next;
         s++;
     }
     printf("%d\n",s);
 }

出队

 char dequeue(linkqueue *q,int e)
 {
     node *p;
     if(q->front==q->rear)
         return -1;
     p=q->front->next;
     e=p->data;
     q->front->next=p->next;
     if(q->rear==p)
         q->rear=q->front;
     free(p);
     return e;
 }

判断队列是否为空

 int queueempty(linkqueue *q)
 {
     if(q->front==q->rear)
         return 1;
     else
         return 0;
 }

菜单

 void menu()
 {
     printf("           链队列试验统一界面               \n");
     printf("********************************************\n");
     printf("1 建立链队列!                              *\n");
     printf("2 链队列入队操作!                          *\n");
     printf("3 链队列出队操作!                          *\n");
     printf("4 求链队列长度!                            *\n");
     printf("5 判断链队列是否为空!                      *\n");
     printf("6 输出链队列!                              *\n");
     printf("7 销毁链队列!                              *\n");
     printf("0 退出!                                    *\n");
     printf("********************************************\n");
 }

测试

int main(void)
{
linkqueue ptr;
int sel;
int num;
initqueue(&ptr);
while(1)
{
menu();
printf(“please input command:\n”);
scanf("%d",&sel);
switch(sel)
{
case 1:if(yes1)
{
printf(“此时表已创建!不能再次创建!\n”);
break;
}
else
creatqueue(&ptr);break;
case 2:if(yes
0)
{
printf(“此时表未创建!不能入队!\n”);
break;
}
else
{
printf(“请输入队的元素值:”);
scanf("%d",&num);
enqueue(&ptr,num);
break;
}
case 3:if(yes0)
{
printf(“此时表为创建!不能出队!\n”);
break;
}
else
{
num=dequeue(&ptr,num);
printf(“目前出队的元素是%d”,num);
break;
}
case 4:if(yes
0)
{
printf(“此时链队列未创建!不能求其长度!\n”);
break;
}
lenqueue(&ptr);
break;
case 5:if(yes0)
{
printf(“此时表未创建!不能判断是否为空!\n”);
break;
}
else
{
if(queueempty(&ptr))
printf(“此时队列为空队列!\n”);
else
printf(“此时队列为非空队列!\n”);
break;
}
case 6:if(yes
0)
{
printf(“此时链队列未创建!不能输出!\n”);
break;
}
disqueue(&ptr);
break;
case 7:if(yes==0)
{
printf(“此时链队列未创建!不能销毁!\n”);
break;
}
destroyqueue(&ptr);
printf(“销毁成功\n”);
break;
case 0:exit(1);break;
default:printf(“输入命令错误!请重新输入:\n”);
break;
}
}
return OK;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值