单链表

单链表

概念

与数组不同的是链表的存储单元不一定是连续的

每个结点除了数据域之外保存了后继指针

关于头节点和头指针

头指针指的是链表中第一个结点的存储位置(若无头节点则指针指向第一个节点,否则指向头节点)

头节点则是为了对第一个元素插入/删除节点时,与其他节点操作一致

链表可以没有头节点但不可以没有头指针

c++实现(建立,插入,删除,反转,打印)

#include<iostream>
using namespace std;

struct Node {
	int elem;
	Node* next;
	Node(int e) :elem(e), next(nullptr) {}
};

class List {
public:
	List() {
		head = new Node(0);
	}
	void insert(const int& e) {  //头插法,结合find函数可以再指定元素前插入
		Node* node = new Node(e);
		node->next= head->next;
		head->next = node;
		++head->elem;  //头节点的数据域记录链表长度
	}
	void remove(const int& e) {  //删除指定节点
		Node* node = find(e);
		Node* temp = node->next;
		node->next = node->next->next;
		delete temp;
	}
	Node* find(const int& e) {  //返回的是查找结点的上一个元素
		Node* node = head;
		while (node)
		{
			if (node->next->elem == e)
				break;
			node = node->next;
		}
		return node;
	}
	void reverse() {  //反转链表
		Node* first = head->next;
		Node* second = head->next->next;
		Node* third = head->next->next->next;

		first->next = nullptr;
		while (third) {
			second->next = first;
			first = second;
			second = third;
			third = third->next;  //如果只用俩指针p,q,这一步就会出错
		}
		second->next = first;
		head->next = second;
	}
	void print()
    {
        for(Node * node = head->next;node;node=node->next){
         cout << node->elem <<' ';
	    }
		cout << endl;
    }
private:
	Node* head;  //若需要尾插法,则需要尾指针tail
};
int main()
{
	List myList;
	for (int i = 0; i < 10; ++i)
		myList.insert(i);
	myList.print();
	myList.remove(4);
	myList.print();
	myList.reverse();
	myList.print();
}

1)尾插法需要声明尾指针Node* tail;并且在构造函数中初始化为nullptr

将insert函数改成

	void insert(const int& e) {
		Node* node = new Node(e);
		if (!head->next)
			head->next = node;
		if (tail == nullptr)
			tail = node;
		else
		    tail->next = node;
		    tail = node;
                ++head->elem;
	}

2)插入指定元素之前

	void insert_position(const int& e, int p) {
		Node* pos = find(p);
		Node* node = new Node(e);
		node->next = pos->next;
		pos->next = node;
	}

3)另外链表反转的错误写法是

	void reverse() {  //反转链表
		Node* p = head->next;
		Node* q = head->next->next;
    
		p->next = nullptr;
		while (q->next) {  //不管怎么样,得用仨指针
			q->next = p;
			p = q;
			q = q->next;  //导致链表原地打转
		}
		q->next = p;
		head->next = q;
	}
posted @ 2020-08-10 23:30  kite97  阅读(129)  评论(0编辑  收藏  举报