循环链表,栈,队列,链表实现

来源:互联网 发布:钉钉网络异常 编辑:程序博客网 时间:2024/06/08 13:51

明天要面试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就是最后一次循环结束后的p1p3=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,然后将栈顶移动到sstack* 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就是指向了topstack* 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最后,并且将队尾指针指向sHQ->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;}





原创粉丝点击