又一篇 链表练习

#ifndef LINK_H
#define LINK_H

#include <memory>
#include <iostream>

struct ListNode {
    int val;
    std::shared_ptr<ListNode> next;
};

struct LinkList{
    std::shared_ptr<ListNode> begin;
    std::shared_ptr<ListNode> end;
};

std::shared_ptr<ListNode>  CreateNode(int i);
bool CreateLinkList(LinkList& ll,std::shared_ptr<ListNode>& insertNode);
bool AppendNode(LinkList& ll,std::shared_ptr<ListNode>& insertNode);
void PrintLinkList(const LinkList& ll);
std::shared_ptr<ListNode> FindInLinkList(LinkList& ll,int findValue);
bool DeleteNode(LinkList& ll,int value);

#endif // LINK_H

  

#include "link.h"

std::shared_ptr<ListNode>  CreateNode(int i){
    std::shared_ptr<ListNode> p(new ListNode());
    p->val = i;
    p->next = nullptr;
    return p;
}

bool CreateLinkList(LinkList& ll,std::shared_ptr<ListNode>& insertNode){
    bool ret = false;

    ll.begin = ll.end = insertNode;

    ret =true;
    return ret;
}

bool AppendNode(LinkList& ll,std::shared_ptr<ListNode>& appendNode){
    bool ret = false;
    if( nullptr == appendNode){
        return ret;
    }

    if(nullptr == ll.end || nullptr == ll.begin){
        ll.begin = ll.end = appendNode;
        ret = true;
        return ret;
    }

    ll.end->next = appendNode;
    ll.end = appendNode;

    ret = true;
    return ret;
}

void PrintLinkList(const LinkList& ll){
    std::shared_ptr<ListNode> p = ll.begin;
    std::cout << "print linklist:  " << std::endl;
    while( p != nullptr ){
        std::cout << p->val << " ";
        p = p->next;
    }
    std::cout << std::endl;
    std::cout << std::endl;
}

std::shared_ptr<ListNode> FindInLinkList(LinkList& ll,int findValue){
    std::shared_ptr<ListNode> p = ll.begin;
    do{
        if(p->val == findValue){
           break;
        }
        p= p->next;
    }while(p != nullptr);

    return p;
}

bool DeleteNode(LinkList& ll,int value){
    bool ret = false;

    if(nullptr == ll.begin || nullptr == ll.end){
        return ret;
    }

    if(ll.begin->val == value){
        if(ll.begin == ll.end){
            ll.begin = ll.end = nullptr;
        }else{
            ll.begin = ll.begin->next;
        }
        ret = true;
        return ret;
    }

    // 遍历链表 查找符合的node
    std::shared_ptr<ListNode> p = ll.begin;
    while(p->next != nullptr){
       if(p->next->val == value){
           break;
       }
       p = p->next;
    }
    if(p->next != nullptr){
        if(p->next == ll.end){
            ll.end = p;
        }
        p->next = p->next->next;
    }

    ret = true;
    return ret;
}

  

// 123.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <assert.h>
#include "link.h"

#include <windows.h>

void TestLinkList() {
	LinkList ll;

	if (!AppendNode(ll, CreateNode(1))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	if (!AppendNode(ll, CreateNode(2))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	if (!AppendNode(ll, CreateNode(3))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	std::shared_ptr<ListNode> p = FindInLinkList(ll, 7);
	assert(p == nullptr);

	p = FindInLinkList(ll, 2);
	assert(p != nullptr && p->val == 2);

	DeleteNode(ll, 3);
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	DeleteNode(ll, 2);
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	DeleteNode(ll, 1);
	// std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	// std::cout << "end:" << ll.end  << " end.val:" << ll.end->val  << std::endl;
	PrintLinkList(ll);

	if (!AppendNode(ll, CreateNode(1))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	if (!AppendNode(ll, CreateNode(2))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	if (!AppendNode(ll, CreateNode(3))) {
		std::cerr << __FUNCTION__ << "().  line:" << __LINE__ << "  Error !" << std::endl;
		return;
	}
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	DeleteNode(ll, 1);
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	DeleteNode(ll, 2);
	std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	std::cout << "end:" << ll.end << " end.val:" << ll.end->val << std::endl;
	PrintLinkList(ll);

	DeleteNode(ll, 3);
	//std::cout << "begin:" << ll.begin << " begin.val:" << ll.begin->val << std::endl;
	//std::cout << "end:" << ll.end  << " end.val:" << ll.end->val  << std::endl;
	PrintLinkList(ll);
}

void TestLinkListMemory() {
	LinkList ll;
 	LinkList ll0;
	while(1)
	{
		for (int i = 1; i<1000; ++i) {
			AppendNode(ll, CreateNode(i));
		}

		for (int i = 1; i<1000; ++i) {
			DeleteNode(ll, i);
		}

		std::cout << "begin:" << ll.begin << std::endl;
		std::cout << "end:" << ll.end << std::endl;
		PrintLinkList(ll);
	}

}

unsigned int dictIntHashFunction(unsigned int key)
{
	key += ~(key << 15);
	key ^= (key >> 10);
	key += (key << 3);
	key ^= (key >> 6);
	key += ~(key << 11);
	key ^= (key >> 16);
	return key;
}

int main(int argc, char *argv[])
{
	TestLinkList();
	TestLinkListMemory();

	return 0;
}

  

时间: 2024-12-28 01:08:54

又一篇 链表练习的相关文章

LeetCode刷题 --基础知识篇-- 链表

题目来源与力扣,传送门在这里. 众所周知,链表是很重要的一种数据结构,但同时也很容易出错,二狗在重温这部分内容时被人指点了一些典型的题目,顺手去leetCode刷了一些,记录如下. <206.单链表反转>(https://leetcode-cn.com/problems/reverse-linked-list/) 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL 1

JS数据结构第三篇---双向链表和循环链表

一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地址.然后头结点的上一个节点,和尾结点的下一个节点都指向null.同时LinkedList类中再增加一个last内部属性,一直指向链表中最后一个节点.结构模拟如图: 同样对外暴露的方法和单向链表一样,只是内部实现稍有变化 双向链表完整设计代码: /** * 自定义双向链表:对外公开的方法有 * append(e

诗经 全文

诗经 全文 (带注释和译文) http://www.edu009.com/Article/HTML/Article_60756.html <诗经> 春秋·孔丘 <诗经>是我国第一部诗歌总集,先秦时代称为“诗”或“诗三百”,孔子加以了整理.汉武帝采纳董仲舒“罢黜百家,独尊儒术”的建议,尊“诗”为经典,定名为<诗经>. <诗经>现存诗歌 305 篇,包括西周初年到春秋中叶共 500 余年的民歌和朝庙乐章,分为风.雅.颂三章. “风”包括周南.召南.邶.鄘.卫.王

C语言实现贪吃蛇之结构链表篇

之前的两篇博客将运用的C语言知识限定在了一般的数组上,但如果已经完整地了解过C语言的话,运用结构和链表会让程序的结构更明了,逻辑更清晰.这篇博客就将介绍如何用结构和链表改善之前的程序. 首先,我们为蛇的节点定义一个结构: typedef struct node{ COORD cor; struct node *next; }node; COORD结构我在上一篇已经介绍过,这里就直接借用了. COORD food = { 3,5 }; node *head; food也相应地由COORD来定义,并

链表题目总结(第二篇)

第一篇里面的问题都是操作一个链表的情况,这一篇主要说说多个链表的一些问题 (1)合并两个已经排序好的链表 //l1, l2两个指针不断的后移 ListNode *MergeSortedLists(ListNode *l1, ListNode *l2) { ListNode newhead(0), *pos = &newhead; while(l1 || l2){ if(!l1) return (pos->next = l2, newhead.next); if(!l2) return (po

单链表反转总结篇

单链表反转总结篇 转自https://www.cnblogs.com/byrhuangqiang/p/4311336.html 单链表的反转是常见的面试题目.本文总结了2种方法. 1 定义 单链表node的数据结构定义如下: class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } } 2 方法1:就地反转法 2.1 思路 把当前链表的下一个节点pCur插入到头结点dummy的下一个节点中

就C语言的指针、链表的原理和各类操作撰写一篇技术博客,说说自己学习C语言指针和链表的体会

一.指向结构体变量的指针变量 指向结构体变量的指针变量的定义形式与一般指针变量的定义形式相同,只是将其指向类型定义为结构体类型即可.例如:        struct person            { charname[20];             char sex;             int age;             float height;            };       struct person *p;则指针变量p,它可以指向struct person类

单链表总结篇

[基本概念]单链表即单向链表,数据结构为一个接一个的结点组成,每个结点有两个成员,一个数据域一个指向下一个结点的指针,如下: struct Node { int data; struct Node *next; }; 单链表基本操作包括链表初始化.插入.删除,其中初始化操作是指让单链表存在一个头结点,其数据域随机,头结点指向下一个结点,每次访问都要从头结点开始访问,插入结点方式有两种,尾部插入和结点前部插入,尾部插入很简单与正常的输入顺序一致,而前部插入需要时常变动头结点的指针,始终让他指向新插

数据结构(复习)链表完结篇

关于链表我们其实有很多要学的东西,书上的东西其实都是皮毛,,只是引领我们而已,但是算法是一个积累的过程!!! 先把基础的东西学好吧!! Coding------------------------------------------------------------------------------------------------------------------- 思路一: 取出原始链表的第一个节点A,然后将该节点作为新链表的头节点. 现在状态为 原始链表:B->C->D->