【算法设计-链表】单链表与双向循环链表

1.单链表代码:包含了尾插法,插入,删除操作。

有头结点的单链表也是为了在第一个位置插入和删除时候容易,不需要另外讨论

#include<stdio.h>

#include<stdlib.h>

typedef struct Linklist

{

int key;

Linklist *next;

}Linklist;

Linklist* create_end()

{

Linklist *head=(Linklist *)malloc(sizeof(Linklist));

Linklist *e,*p;

e=head;

printf("输入值?以#结束\n");

int ch;

while((scanf("%d",&ch))==1)

{

p=(Linklist *)malloc(sizeof(Linklist));

p->key=ch;

e->next=p;

e=p;

}

e->next=NULL;

printf("done\n");

return head;//这里返回头结点而不是head->next,目的就是为了后面的插入和删除时候可以在第一个位置插入和删除

}

void add(Linklist* head)

{

Linklist *q=head;

Linklist *p=(Linklist*)malloc(sizeof(Linklist));

int ch;

printf("要插入的位置:");

fflush(stdin);

scanf("%d",&ch);

int i=1;//i要从1开始

while(i!=ch)

{

q=q->next;

i++;

}

p->next=q->next;

q->next=p;

printf("要插入的数据是多少:");

fflush(stdin);

scanf("%d",&ch);

p->key=ch;

}

void delete_s(Linklist* head)

{

printf("要删除第几个位置:");

int ch;

fflush(stdin);

scanf("%d",&ch);

Linklist *p=head;

Linklist *q=p->next;

int i=1;

while(i!=ch)

{

q=q->next;

p=p->next;

i++;

}

p->next=q->next;

printf("删除了%d",q->key);

delete q;

}

void show_Linklist(Linklist* head)

{

Linklist* p=head->next;//为了不输出头结点的值要从head->next开始

while(p->next!=NULL)

{

printf("%d->",p->key);

p=p->next;

}

printf("%d",p->key);

}

int main(void)

{

Linklist *head=new Linklist;

head=create_end();

add(head);

show_Linklist(head);

delete_s(head);

show_Linklist(head);

return 0;

}

结果展示:

2.双向循环链表:包含尾插,插入,删除

本文中循环链表包含头结点。这样做的好处是为了在第一个位置插入和删除都很容易

插入操作:

注意:要始终以头结点后面一个节点作为标杆指针计算

代码:

#include<stdio.h>

#include<stdlib.h>

typedef struct Linklist

{

int key;

Linklist *prior;

Linklist *next;

}Linklist;

Linklist* create_end()

{

Linklist *head=(Linklist *)malloc(sizeof(Linklist));

head->key=0;

Linklist *e,*p;

e=head;

printf("输入值?以#结束\n");

int ch;

while((scanf("%d",&ch))==1)

{

p=(Linklist *)malloc(sizeof(Linklist));

p->key=ch;

e->next=p;

p->prior=e;

e=p;

}

e->next=head;

head->prior=e;

printf("done\n");

return head;

}

void add(Linklist* head)

{

Linklist *p=head->next;

Linklist *r=(Linklist*)malloc(sizeof(Linklist));

int ch;

printf("要插入的位置:");

fflush(stdin);

scanf("%d",&ch);

int i=1;

while(i!=ch)

{

p=p->next;

i++;

}

printf("要插入的数据是多少:");

scanf("%d",&ch);

r->key=ch;

r->next=p;//注意这里的写法

r->prior=p->prior;

r->prior->next=r;

p->prior=r;

}

void delete_s(Linklist* head)

{

Linklist *p=head->next;//这里要有next

if(p->next==head)

{

printf("不能删除了,已经空了!\n");

}

printf("要删除第几个位置:");

int ch;

fflush(stdin);

scanf("%d",&ch);

int i=1;

while(i!=ch)

{

p=p->next;

i++;

}

p->prior->next=p->next;

p->next->prior=p->prior;

printf("删除了%d\n",p->key);

delete p;

}

void show_Linklist(Linklist* head)

{

Linklist *p=head->next;

while(p->next!=head)

{

printf("%d->",p->key);

p=p->next;

}

printf("%d",p->key);

}

int main(void)

{

Linklist *head=new Linklist;

head=create_end();

add(head);

show_Linklist(head);

delete_s(head);

show_Linklist(head);

return 0;

}

时间: 2024-10-09 22:54:17

【算法设计-链表】单链表与双向循环链表的相关文章

009实现一个算法来删除单链表中的一个结点,只给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点,因为是单链表,不知道前驱,只知道 后继结点,直接删除会使链表断开.不过我们可以删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =

cc150:实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针. 例子: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不需要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你只有一个指向要删除结点的指针,如果直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这种情况下, 你只能另觅他径.重新审视一下这个问题,我们只能获得从c结点开始后的指针, 如果让你删除c结点后的某个结点,那

cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你仅仅有一个指向要删除结点的指针,假设直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这样的情况下, 你仅仅能另觅他径.又一次审视一下这个问题,我们仅仅能获得从c结点開始后的指针, 假设让你删除c结点后的

常见算法题:单链表二路归并

题目:现有两个递增的单链表L1和L2,设计一个算法将L1与L2的所有结点归并到递增的单链表L3中.要求:空间复杂度为O(1). 思路:本题可采用二路归并思路,但题目要求空间复杂度为O(1),因此不能复制结点,只能破坏L1和L2将结点插入到L3中. 代码: void Merge(LinkList &L1,LinkList &L2,LinkList &L3) { LinkList *p=L1.head->next, *q=L2.head->next; LinkList *p

4.2.2 算法之美--单链表实现

按照书上的要求实现了一下单链表:单链表的实现可能以前看过几次了:现在想想最主要的几个操作算法应该能够写了吧:遇到的问题: 1. 链表节点写成private;所已给出了访问的接口: 2.模板类的.h和.cpp实现写在同一个文件: 3.感觉以后的数据结构实现还是用纯c的实现好一些:然后书主要是思路 节点类: #ifndef SINGLELIST_LISTNODE_H_ #define SINGLELIST_LISTNODE_H_ template <class T> class ListNode

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT

算法初探001——单链表反转

单链表的反转问题是一道很基本的问题.题目如下: 有一个单链表 1 ->2->3->4->5->6 反转后链表为:6->5->4->3->2->1. 方法一 解析:可以使用三个指针pre ,temp,next对逐个节点进行反转.详细流程如下: (4) 初始状态 pre = head; tmp = head->next; pre->next = null; (2)第一次循环: next = tmp->next; tmp->ne

008实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n. 然后.我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变. 那么, 当第二个指针指到空时.第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data

009实现一个算法来删除单链表中的一个结点,仅仅给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点.由于是单链表,不知道前驱,仅仅知道 后继结点,直接删除会使链表断开.只是我们能够删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =