链表,顺序表的基本操作及其实现的栈与队列

1,顺序表

在c里面,这一部分也就是静态表和动态表的实现,插入,删除有丁点意思。

静态表靠数组和长度实现(注意长度这一点,因为它反映了当前表内容长度,十分重要)

动态表依靠申请连续空间实现(结构体内部包括首地址,当前规模以及长度)

插入:

	int *p;
	p=&(w.a[k-1]);
	int *q;
	for(q=&(w.a[w.length-1]);q>=p;--q)
	{
		*(q+1)=*q;
	}
	*q=m;
	++w.length;
删除同理

2,链表:

链表结构体很简单:

typedef struct Node{
	int data;
	struct Node *next;
}; 
typedef Node* Linkedlist;

首先是首插法和尾插法:

int Touinsert(Linkedlist &l)
{
	Lnode* r,s,m;
	l=r;
	for(int i=0;i<=length;i++)
	{
		s=(Lnode *)malloc(sizeof(Lnode));
		s->data=i;
		s->next=L;
		r=L;        //!
	}
	for(int i=0;i<=length;i++)
	{
		s=(Lnode *)malloc(sizeof(Lnode));
		s->data=i;
		L->next=s;
		s->next=m;
		m=s;
	} 
}//头插法对于存不存在头节点没有特殊需求,反而头结点会导致头插法不那么方便
/*
int Weiinsert(LInkedlist &l)
{
	Lnode *r,m;
	r=L;
		for(int i=0;i<=length;i++)
	{
		s=(Lnode *)malloc(sizeof(Lnode));
	    r->next=s;
	    r=s;
	}
}//尾插法在此处就有问题——我们不可能r=L后(此时L为NULL)通过对r的操作改变L,首结点的本质是使得初定义的指针可以和L共同指向一个有意义的节点,通过初定义的指针直接影响L
*/ 
int Weiinsert(LInkedlist *l)
{
	L=(Lnode*)malloc(sizeof(Lnode));//注意定义首节点的方法 
	Lnode *r,*s;
	r=L;
	for(int i=0;i<=length;i++)
	{
		s=(Lnode *)malloc(sizeof(Lnode));
		s->data=i;
		r->next=s;
		r=s;
	}
}
如上所述,尾插法记得加首节点,会令操作简化一些,并且逻辑不会冲突。

接下来,是循环链表,双链表,循环双链表的基本操作,并不复杂,也就是在基本的尾插法上加一些操作即可实现。

void init_CircleLinkedList(Linkedlist &l1,int t)
{
	
	Linkedlist m,a;
	m=(Linkedlist)malloc(sizeof(Node));
	m->data=t;
	l1=m;               //!!!
	m->next=NULL;
	
	for(int i=0;i<t;i++)
	{
		a=(Linkedlist)malloc(sizeof(Node));
		a->data=i;
		m->next=a;
		m=m->next;
	
		if(i==t-1)
		{
			m->next=l1->next;
			continue;
		}
	}
}
void init_DoubleLInkedlist(Linkedlist1 &l2,int t)
{
	Linkedlist1 m,a;
	m=(Linkedlist1)malloc(sizeof(Node1));
	m->data=t;
	l2=m;
	m->next1=NULL;
	m->prior=NULL;
	for(int i=0;i<t;i++)
	{
		a=(Linkedlist1)malloc(sizeof(Node1));
		a->data=i;
		m->next1=a;
		a->prior=m;
        m=a;
        if(i==t-1)
        {
        	m->next1=NULL;
        }
	}
}
void init_DoubleLCircleInkedlist(Linkedlist1 &l2,int t)
{
	Linkedlist1 m,a;
	m=(Linkedlist1)malloc(sizeof(Node1));
	m->data=t;
	l2=m;
	m->next1=NULL;
	m->prior=NULL;
	for(int i=0;i<t;i++)
	{
		a=(Linkedlist1)malloc(sizeof(Node1));
		a->data=i;
		m->next1=a;
		a->prior=m;
        m=a;
        if(i==t-1)
        {
        	m->next1=l2;
        	l2->next->prior=m;
        }
	}
}
最后,我特别粘贴一张双链表的插入操作的图:

注意:在双向链表中,得到节点只能通过priori或是next得到先序节点或是后继节点,所以我们在连好后/先节点与插入节点之前不可断链。

概括而言:顺序是s的后继连向p的后继,p的后继的前驱连上s(先把p的后继处理),s的前驱指向p,p的后继指向s。(之后把p连向s);

3,栈与队列

栈和队列基于顺序表抑或是链表实现的,他们不过是在后者的操作的基础上加上特定的操作罢了。

typedef struct{
	char a[MAXSIZE];
	int top;
}SqStack;
typedef struct{
	int *base;
	int *top;
	int stacksize;
}SqStack1;

以上是顺序栈的结构体,静态的top初始化为-1,动态的top=base指向申请空间首位置。

注意:入栈是先升指针再入栈。(*(++S.top)=e)

           出栈是先赋值给参数再降指针(*(S.top--)=e)(反了,懒得改能看懂就ok)

链栈不很常见,头节点+首插法就ok,存取对象都是头节点的next即可。

队列:

以普通静态队列为例:

typedef struct{
	int elem[100];
	int rear,front;
	int SqSize;
}SqQueue;
以上结构体;

入队出队:

void Basic_Operate(SqQueue &S,int a,int m)
{
	if(m==1)
	{
		S.elem[S.top++]=a;
	}
	if(m==0)
	{
		a=S.elem[S.rear++];
		printf("%d",a);
	}
}
循环动态队列:

typedef struct{
	int *base;
	int top;
	int rear;
}CircleQueue;
以上结构体;

int init_CQ(CircleQueue &CQ)
{
	CQ.base=(int *)malloc(sizeof(100));
	CQ.top=0;
	CQ.rear=0;
}
int EnQueue(Circle &CQ,int a)
{
	if((CQ.rear+1+100)%100==CQ.top){
		return ERROR;
	}
	else
	{
		CQ.base[CQ.rear]=a;
		CQ.rear=(CQ.rear+1+100)%100;
		return 1;
	}
}
int DeQueue(CirCleQueue &CQ,int a)
{
	if(CQ.top==CQ.rear)
	{
		return ERROR;
	}
	else
	{
		a=CQ.base[top];
		CQ.top=(CQ.top+1+100)%100;
		return a;
	}
}

以上初始化/插入/删除操作;

注意:1,判满条件:(CQ.rear+1)%MAXSIZE==CQ.top;

           2,判空条件:CQ.rear==CQ.top;

           3,CQ.top=(top+1)%MAXSIZE;

最后,在脑海里要形成栈和队列各自指针的位置,栈只有一个头指针top,永远指向存在值的最上面的地址,队列有两个指针,首指针和尾指针,尾进头出,尾指针永远指向最后一个入队元素下一个的空位置,头指针永远指向即将出队的元素,除非队空,一定有值。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值