明天要面试inginging
发现把代码放在博客里翻看的时候,好方便,所以花点时间来把自己认为基础的东西放过来,仅供自己复习复习
1.循环链表
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
/*
1.建立一个具有n个链节点的循环链表
2.确定第一个报数人的位置;
3.不断从链表中删除节点,直到链表为空;
*/
typedef struct LNode
{
int data;
struct LNode* link;
}LNode, *LinkList;
void baoshu(int n, int k , int m)
{
//n是总人数,k是第一个开始报数的人,m是列出者喊道的数;
LinkList p, r, curr;
//建立循环链表
p = (LinkList)malloc(sizeof(LNode));
p->data = 0;
p->link = p;
curr = p;
for(int i = 1; i<n; i++)
{
LinkList t=(LinkList)malloc(sizeof(LNode));
t->data = i;
t->link = curr->link;
curr->link = t;
curr = t;
}
//把指针移动到第一个报数的人
r = curr;
printf("%d\n",k);
while(k--)
{ printf("%d\n",k);
r = p;
p = p->link;
}
while(n--)
{
for(int s = m-1; s--;r=p,p=p->link);
r->link = p->link;
printf("%d->", p->data);
free(p);
p = r->link;
}
}
int main()
{
baoshu(6,3,2);
}
2.单链表
功能包括:链表的创建,求长,打印,增加一个元素,删除一个元素,排序,反转
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
using namespace std;
typedef struct student
{
int data;
struct student * next;
}node;
node* creat()
{
node * head, *p,*s;
int x, cycle = 1;
head=(node *)malloc(sizeof(node));
p=head;
while(cycle)
{
printf("\nplease input the data:");
scanf("%d", &x);
if(x!=0)
{
s=(node*)malloc(sizeof(node));
s->data=x;
printf("\n%d",s->data);
p->next = s;
p = s;
}
else cycle = 0;
}
head = head->next;
p->next = NULL;
printf("\n %d",head->data);
return head;
}
int length(node * head)
{
int n=0;
node* p;
p=head;
while(p!=NULL)
{
p=p->next;
n++;
}
return n;
}
void print(node* head)
{
node *p;
int n;
n=length(head);
printf("\n Now, Thesese %d records are:\n", n);
p=head;
//if(p!=NULL)
//{
while(p!=NULL)
{
printf("\n %d ", p->data);
p=p->next;
}
//}
}
node* del(node* head, int num)
{
node* p1, *p2;
p1=head;
while(p1->data!=num&&p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(num==p1->data)
{
if(p1==head)
{
head=p1->next;
free(p1);
}
else
{
p2->next=p1->next;
free(p1);
}
}
else
{
printf("\n%d could not be found.", num);
}
return head;
}
node* insert(node* head, int num)
{
node *p0,*p1,*p2;
p1=head;
p0=(node*)malloc(sizeof(node));
p0->data=num;
while(p0->data>p1->data&&p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(p0->data<p1->data)
{
if(p1==head)
{
p0->next=p1;
head=p0;
}
else
{
p2->next=p0;
p0->next=p1;
}
}
else
{
p1->next=p0;
p0->next=NULL;
}
return head;
}
node* sort(node* head)
{
node* p,*p2,*p3;
int n;
int temp;
n = length(head);
if(head==NULL||head->next==NULL)
return head;
p=head;
for(int j=1; j<n;++j)
{
p=head;
for(int i =0; i<n-j;++i)
{
if(p->data>p->next->data)
{
temp = p->data;
p->data=p->next->data;
p->next->data=temp;
}
p=p->next;
}
}
return head;
}
node* reverse(node* head)
{
node* p1, *p2, *p3;
if(head==NULL||head->next==NULL)
{
return head;
}
p1=head;
p2=p1->next;
while(p2)
{
//为什么这样呢?是因为,我总是将p1,p2之间的指针方向变换,但是,始终p2,p3之间是原来的顺序
//不断的进行p1,p2向后移动,这样就可以达到反转的目的了
//并且可以证明,这个方法没有错误,因为当我的p2要是空的话,我这个循环就结束了,但是我的p1之前的已经反转完毕
//唯一需要注意的是,在循环技术后,要将head->next=NULL
//而且此时我的head就是最后一次循环结束后的p1
p3=p2->next;
p2->next = p1;
p1=p2;
p2=p3;
}
head->next=NULL;
head=p1;
return head;
}
int main()
{
node * p=creat();
length(p);
print(p);
/*
del(p, 5);
length(p);
print(p);
p=insert(p,1);
length(p);
print(p);
*/
p=sort(p);
print(p);
p=reverse(p);
print(p);
}
3.栈的相关操作
主要就是push,pop操作,定义了两个指向节点的指针,分别是bottom和top作为栈底和栈顶
#include <iostream>
#include <stdio.h>
#include <conio.h>
using namespace std;
typedef struct student
{
int data;
struct student* next;
}node;
typedef struct stack
{
node* top, *bottom;
}stack;
//入栈
//涉及到插入问题,首先要新建一个节点,重要
//这里需要注意的一点是,HQ是一个栈,因此,我的操作是在栈的基础上
//入栈有两个情况:1.栈为空:则很简单,让栈顶以及栈底都指向新建的节点
//2.然后就是不为空的时候,让栈顶的下一个元素指向新建s,然后将栈顶移动到s
stack* push(stack* HQ, int x)
{
node* p, *s;
s=(node*)malloc(sizeof(node));
s->data= x;
s->next=NULL;
if(HQ->bottom==NULL) //栈为空
{
HQ->bottom = s;
HQ->top = s;
}
else
{
HQ->top->next = s;
HQ->top=s;
}
//free(s);
return HQ;
}
//出栈
//考虑了三种情况,栈为空,栈有一个节点,栈有多个节点
//这里必须注意的是,要对stack->top以及stack->bottom 进行赋值
//有一点要注意的是,删除节点的时候,一定要保持让他和前面的节点之间的联系不能丢掉
//所以后面我们进行循环的判断是用了p->next!=HQ->top
//循环结束后,p->next就是指向了top
stack* pop(stack* HQ)
{
node* p;
int x;
if(HQ->bottom==NULL)
{
printf("\n empty");
}
else
{
p=HQ->bottom;
if(HQ->bottom == HQ->top)
{
x=HQ->bottom->data;
HQ->bottom=NULL;
HQ->top=NULL;
printf("\n pop(%d)",x);
return HQ;
}
else
{
while(p->next!=HQ->top)
{
p= p->next;
}
x=HQ->top->data;
//释放top的内存
free(HQ->top);
HQ->top = p;
HQ->top->next = NULL;
}
}
printf("\n pop(%d)",x);
return HQ;
}
int main()
{
//node* p = (node*)malloc(sizeof(node));
stack * Stack = (stack*)malloc(sizeof(stack));
Stack->bottom = NULL;
Stack->top = NULL;
push(Stack,11);
push(Stack ,12);
pop(Stack);
for(int i = 1; i <= 15; i++)
{
push(Stack, i);
}
while(Stack->bottom!=Stack->top)
{
pop(Stack);
}
free(Stack);
return 0;
}
4.队列
这里只定义了两个操作,入队和出队,其实和栈的方法以及思路都差不多,入队和入栈是一样的,出队和出栈都要考虑三种情况
这里注意,同样定义了queue这个数据结构,里面包含两个指向节点的指针first, rear;
1.队列为空
2.队列有一个节点,判断方法是首位一样
3.队列有多个节点
#include <iostream>
#include <stdio.h>
#include <string>
#include <conio.h>
using namespace std;
typedef struct student
{
int data;
struct student* next;
}node;
typedef struct linkqueue
{
node *first, *rear;
}queue;
//入队,在队末尾插入
queue* insert(queue* HQ, int x)
{
node* s;
s=(node*)malloc(sizeof(s));
s->data=x;
s->next=NULL;
if(HQ->rear==NULL)
{
HQ->first=s;
HQ->rear=s;
}
else
{
HQ->rear->next=s;//首先将s链接到queue最后,并且将队尾指针指向s
HQ->rear=s;
}
return HQ;
}
//出队,从队首开始删除一个节点
queue* del(queue* HQ)
{
node* p;
int x;
if(HQ->first==NULL)
{
printf("\n yichu");
}
else
{
x=HQ->first->data;
p = HQ->first;
if(HQ->first==HQ->rear)
{
free(p);
HQ->first = NULL;
HQ->rear = NULL;
}
else
{
HQ->first = HQ->first->next;
free(p);
}
}
return HQ;
}