学习笔记之链表

阅读 15

2024-09-22

题目:有一串已经从小到大排好序的数2 3 5 8 9 10 18 26 32。现需要往这串数中插入6使其得到的新序列仍符合从小到大排列。

输入样例

9
2 3 5 8 9 10 18 26 32
6

输出样例

2 3 5 6 8 9 10 18 26 32

采用链表的方法实现

#include<stdio.h>
#include<stdlib.h>


//创建一个结构体用来表示链表的结点类型
struct node{
	int data;
	struct node *next;
};

int main(){
	struct node *head,*p,*q,*t;
	int i,n,a;
	scanf("%d",&n);
	head=NULL;//头指针初始为空
	//循环读入n个数 
	for(int i=1;i<=n;i++){
		scanf("%d",&a);
		//动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
		p=(struct node *)malloc(sizeof(struct node));
		//将数据存储到当前结点的值中
		p->data=a;
		//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空 
		p->next=NULL;
		if(head==NULL){
			//如果这是第一个创建的结点,则将头指针指向这个结点 
			head=p;	
		}else{
			//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点 
			q->next=p;
		}
		//指针q也指向当前结点 
		q=p;
	} 
	//读入待插入的数 
	scanf("%d",&a);
	//从链表头部开始遍历 
	t=head; 
	//当没有到达链表尾部的时候循环 
	while(t!=NULL){
		//如果当前结点下一个结点的值大于待插入数,将数插入到中间 
		if(t->next->data>a){
			//动态申请一个空间,用来存放新增结点 
			p=(struct node *)malloc(sizeof(struct node));
			p->data=a;
			//新增结点的后继指针指向当前结点的后继指针所指向的结点
			p->next=t->next;
			//当前结点的后继指针指向新增结点
			t->next=p;
			//插入完毕退出循环 
			break; 
		}
		t=t->next; 
	}
	
	t=head;
	while(t!=NULL){
		printf("%d ",t->data);
		t=t->next;
	} 
	return 0; 
}
 

模拟链表(用数组的方式实现)

#include<stdio.h>

int main(){
	int data[101],right[101];
	int i,n,t,len;
	//读入已有的数
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&data[i]);
	} 
	len=n;
	//初始化数组right
	for(i=1;i<=n;i++){
		if(i!=n){
			right[i]=i+1;
		}else{
			right[i]=0;
		}
	} 
	//直接在数组data的末尾增加一个数
	len++;
	scanf("%d",&data[len]);
	
	//从链表的头部开始遍历
	t=1;
	while(t!=0){
		//如果当前结点下一个结点的值大于待插入数,将数插入到中间 
		if(data[right[t]]>data[len]){
			//新插入数的下一个结点标号等于当前结点的下一个结点编号 
			right[len]=right[t]; 
			//当前结点的下一个结点编号就是新插入数的编号
			right[t]=len;
			//插入完成跳出循环
			break; 
		}
		t=right[t];
	} 
	
	//输出链表中的所有数
	t=1;
	while(t!=0){
		printf("%d ",data[t]);
		t=right[t];
	} 
	return 0; 
}
 

单链表

#include <cstring>   // 包含字符串处理库
#include <cstdlib>   // 包含标准库,用于内存分配和转换
#include <iostream>  // 包含输入输出流库
using namespace std; // 使用标准命名空间

// 声明一个链表节点的结构体
typedef struct Node
{
    int data;              // 存储节点的值
    struct Node *next;     // 指向下一个节点的指针
} *LinkedList, LNode; // 定义LinkedList为Node的指针,LNode为Node

// 尾插法创建单链表
void CreatLinkedList(LinkedList &L, int n)   
{
    L = (LinkedList)malloc(sizeof(LNode));  // 为头节点分配内存
    L->next = NULL;                         // 初始化下一个指针为NULL
    L->data = 0;                            // 初始化节点计数为0
    LinkedList Tail = L;                    // 尾指针,用于跟踪链表的末尾
    cout << "Enter " << n << " number(s)" << endl; // 提示用户输入数字
    for(int i = 0; i < n; i++)              // 循环读取'n'个数字
    {
        LinkedList Temp = (LinkedList)malloc(sizeof(LNode)); // 为新节点分配内存
        cin >> Temp->data;                  // 读取数据到新节点
        Tail->next = Temp;                  // 将新节点链接到链表末尾
        Tail = Temp;                        // 移动尾指针到新节点
        Temp = NULL;                        // 将Temp设为NULL(不严格必要)
        L->data++;                          // 增加头节点中的计数
    }
    Tail->next = NULL;                      // 确保最后一个节点的下一个指针为NULL
}

// 获取指定位置的元素
bool GetElem(int &e, int i, LinkedList L) 
{
    while(L != NULL && i > 0)              // 遍历链表,直到达到指定索引
    {
        i--;                                // 索引递减
        L = L->next;                        // 移动到下一个节点
    }
    if(i == 0 && L != NULL)                // 如果索引为0且当前节点不为NULL
    {
        e = L->data;                       // 获取当前节点的数据
        return true;                       // 返回成功
    }
    else return false;                     // 返回失败
}

// 在指定位置插入元素
bool InsertElem(int e, int i, LinkedList L)  
{
    if(i > L->data + 1 || i < 1)           // 检查位置是否有效
        return false;                      // 如果无效,返回false
    else
    {
        L->data++;                         // 增加节点计数
        while(i > 1)                       // 遍历到插入位置的前一个节点
        {
            i--;                           // 索引递减
            L = L->next;                   // 移动到下一个节点
        }
        LinkedList Temp = (LinkedList)malloc(sizeof(LNode)); // 为新节点分配内存
        Temp->data = e;                    // 设置新节点的数据
        Temp->next = L->next;              // 将新节点链接到下一个节点
        L->next = Temp;                    // 将当前节点链接到新节点
        Temp = NULL;                       // 将Temp设为NULL(不严格必要)
        return true;                       // 返回成功
    }
}

// 删除指定位置的元素
bool DeleteElem(int i, LinkedList L) 
{
    if(i > L->data || i < 1)               // 检查位置是否有效
        return false;                      // 如果无效,返回false
    else
    {
        L->data--;                         // 减少节点计数
        while(i > 1)                       // 遍历到删除位置的前一个节点
        {
            i--;                           // 索引递减
            L = L->next;                   // 移动到下一个节点
        }
        LinkedList Temp = L->next;        // 存储要删除的节点
        L->next = Temp->next;              // 将当前节点链接到被删除节点的下一个节点
        free(Temp);                        // 释放被删除节点的内存
        Temp = NULL;                       // 将Temp设为NULL(不严格必要)
        return true;                       // 返回成功
    }
}

// 销毁单链表并释放内存
bool DestoryLinkedList(LinkedList &L)   
{
    if(L->next != NULL)                    // 如果还有更多节点要处理
        DestoryLinkedList(L->next);       // 递归销毁下一个节点
    free(L);                               // 释放当前节点的内存
    L = NULL;                              // 将指针设为NULL
    return true;                           // 返回成功
}

// 清空单链表但不销毁头节点
bool ClearLinkedList(LinkedList &L) 
{
    DestoryLinkedList(L->next);            // 清除下一个节点
    L->next = NULL;                        // 将头节点的下一个指针设为NULL
    L->data = 0;                           // 重置节点计数为0
    return true;                           // 返回成功
}

// 遍历并打印链表的所有元素
void GetLinkedList(LinkedList L)    
{
    LinkedList Head = L->next;             // 从第一个实际节点开始
    while(Head != NULL)                     // 遍历链表直到结束
    {
        cout << Head->data << endl;        // 打印当前节点的数据
        Head = Head->next;                 // 移动到下一个节点
    }
}
 
int main()
{
    int n, i, Elem;                         // 用于存储元素个数、位置和元素值的变量
    bool Flag;                              // 用于表示成功与否的标志
    LinkedList L;                           // 声明链表

    cout << "How many Elem(s) do you want to create?" << endl; // 提示用户输入元素个数
    cin >> n;                               // 读取元素个数
    CreatLinkedList(L, n);                  // 创建包含'n'个元素的链表
    cout << "Here is what they look like:" << endl; // 显示链表
    GetLinkedList(L);                       // 调用函数打印链表

    cout << "Which position of Elem do you want?" << endl; // 提示输入要获取的元素位置
    cin >> i;                               // 读取位置
    Flag = GetElem(Elem, i, L);             // 尝试获取指定位置的元素
    if(Flag == true)                        // 检查元素是否找到
        cout << Elem << endl;               // 打印找到的元素
    else
        cout << "No matching Elem" << endl; // 如果没有找到,打印错误信息

    cout << "What Elem you wanna insert, and where?" << endl; // 提示用户输入要插入的元素
    cout << "Elem :";
    cin >> Elem;                           // 读取要插入的元素值
    cout << "Position :";
    cin >> i;                              // 读取插入位置
    Flag = InsertElem(Elem, i, L);         // 尝试插入元素
    if(Flag == true)                       // 检查插入是否成功
    {
        cout << "Succeeded!" << endl;      // 打印成功信息
        GetLinkedList(L);                  // 显示插入后的链表
    }
    else
        cout << "Failed!" << endl;         // 打印失败信息

    cout << "Which position of Elem do you want to delete:" << endl; // 提示输入删除位置
    cin >> i;                              // 读取删除位置
    Flag = DeleteElem(i, L);               // 尝试删除指定位置的元素
    if(Flag == true)                       // 检查删除是否成功
    {
        cout << "Succeeded!" << endl;      // 打印成功信息
        GetLinkedList(L);                  // 显示删除后的链表
    }
    else
        cout << "Failed!" << endl;         // 打印失败信息

    if(ClearLinkedList(L))                 // 尝试清空链表
        cout << "LinkedList Cleared!" << endl; // 打印成功信息
    GetLinkedList(L);                      // 验证链表是否为空

    if(DestoryLinkedList(L))               // 尝试销毁链表
        cout << "LinkedList Destroyed!" << endl; // 打印成功信息
    if(L == NULL)                         // 检查链表指针是否为NULL
        cout << "Check" << endl;          // 打印验证信息

    return 0;                              // 程序结束
}

双链表

#include <iostream> 
#include<cstring>
using namespace std;
class ListNode
{
public:
	char data;
	ListNode* prev;
	ListNode* next;
	ListNode()
	{
		data = '0';
		prev = nullptr;
		next = nullptr;
	}
	ListNode(int x)
	{
		data = x;
		prev = nullptr;
		next = nullptr;
	}
};
class DoubleLinkedList
{
public:
	void InsertElement(int, char);//插入功能
	void CreatList(const char*);//创建列表功能
	void SequentialPrint(void);//顺序输出
	void ReversePrint(void);//逆序输出
	void DeleteElement(int);//删除功能
	bool Judge_HUIWEN(void);//判断回文
	DoubleLinkedList()
	{
		head = new ListNode;
		tail = new ListNode;
		length = 0;
		head->data = '0';
		head->next = tail;
		head->prev = nullptr;
		tail->data = '0';
		tail->prev = head;
		tail->next = nullptr;
	}
	~DoubleLinkedList()
	{
		ListNode* p = nullptr;
		while (head)
		{
			p = head;
			head = head->next;
			delete p;
		};
	}
	ListNode* head;
	ListNode* tail;
private:
	int length = 0;
};
void DoubleLinkedList::InsertElement(int position, char element)
{
	if (position <1 || position>length + 1)
	{
		return;
	}
	ListNode* p = head;
	for (int i = 1; i < position; i++)
	{
		p = p->next;
	}
	ListNode* q = p->next;
	ListNode* tmp = new ListNode(element);
	length++;
	tmp->prev = p;
	p->next = tmp;
	tmp->next = q;
	q->prev = tmp;
}
void DoubleLinkedList::CreatList(const char* str)
{
	int x_len = strlen(str);
	for (int i = 0; i < x_len; i++)
	{
		this->InsertElement(i + 1, str[i]);
	}
}
void DoubleLinkedList::SequentialPrint()
{
	if (length == 0)
	{
		return;
	}
	ListNode* p = head->next;
	while (p->next)
	{
		cout << p->data;
		p = p->next;
	}
	cout << endl;
}
void DoubleLinkedList::ReversePrint()
{
	if (length == 0)
	{
		return;
	}
	ListNode* p = tail->prev;
	while (p->prev)
	{
		cout << p->data;
		p = p->prev;
	}
	cout << endl;
}
void DoubleLinkedList::DeleteElement(int location)
{
	if (location > length || location < 1)
	{
		return;
	}
	ListNode* p = head;
	if (location == length)
	{
		for (int i = 1; i < location; i++)
		{
			p = p->next;
		}
		ListNode* q = p->next;
		delete q;
		length--;
		p->next = this->tail;
		this->tail = p;
	}
	else
	{
		for (int i = 1; i < location; i++)
		{
			p = p->next;
		}
		ListNode* q1 = p->next;
		ListNode* q2 = p->next->next;
		delete q1;
		length--;
		p->next = q2;
		q2->prev = p;
	}
}
bool DoubleLinkedList::Judge_HUIWEN()
{
	ListNode* p = head;
	ListNode* q = tail;
	while (true)
	{
		if ((p == q) || (p->prev == q))return 1;
		if (p->data != q->data)return 0;
		p = p->next;
		q = q->prev;
	}
}
int main() {
	DoubleLinkedList obj;
	char temp[105] = {};
	cin >> temp;
	obj.CreatList(temp);
	if (obj.Judge_HUIWEN())
	{
		obj.SequentialPrint();
		cout << "True" << endl;
	}
	else
	{
		obj.SequentialPrint();
		cout << "False" << endl;
	}
	while (true)
	{
		int x;
		cin >> x;
		obj.DeleteElement(x);
		obj.SequentialPrint();
	}
	system("pause");
	return 0;
}

循环链表

#include <iostream>
#include <cstring>
using namespace std;

class ListNode {
public:
    char data;
    ListNode* next;
    
    ListNode() : data('0'), next(nullptr) {}
    ListNode(char x) : data(x), next(nullptr) {}
};

class CircularLinkedList {
public:
    CircularLinkedList();
    ~CircularLinkedList();
    
    void InsertElement(int position, char element);
    void CreateList(const char* str);
    void SequentialPrint() const;
    void DeleteElement(int position);
    bool Judge_HUIWEN() const;

private:
    ListNode* head;
    int length;
};

CircularLinkedList::CircularLinkedList() : head(nullptr), length(0) {}

CircularLinkedList::~CircularLinkedList() {
    if (head) {
        ListNode* current = head;
        do {
            ListNode* nextNode = current->next;
            delete current;
            current = nextNode;
        } while (current != head);
    }
}

void CircularLinkedList::InsertElement(int position, char element) {
    if (position < 1 || position > length + 1) {
        return;
    }
    ListNode* newNode = new ListNode(element);
    if (length == 0) {
        head = newNode;
        newNode->next = head; // point to itself
    } else {
        ListNode* current = head;
        for (int i = 1; i < position - 1; i++) {
            current = current->next;
        }
        newNode->next = current->next;
        current->next = newNode;
        if (position == 1) {
            head = newNode; // update head if inserted at the beginning
        }
    }
    length++;
}

void CircularLinkedList::CreateList(const char* str) {
    for (int i = 0; i < strlen(str); i++) {
        InsertElement(i + 1, str[i]);
    }
}

void CircularLinkedList::SequentialPrint() const {
    if (length == 0) {
        return;
    }
    ListNode* current = head;
    do {
        cout << current->data;
        current = current->next;
    } while (current != head);
    cout << endl;
}

void CircularLinkedList::DeleteElement(int position) {
    if (position < 1 || position > length) {
        return;
    }
    ListNode* current = head;
    if (position == 1) {
        if (length == 1) {
            delete head;
            head = nullptr;
        } else {
            ListNode* tail = head;
            while (tail->next != head) {
                tail = tail->next;
            }
            tail->next = head->next;
            delete head;
            head = tail->next;
        }
    } else {
        for (int i = 1; i < position - 1; i++) {
            current = current->next;
        }
        ListNode* toDelete = current->next;
        current->next = toDelete->next;
        delete toDelete;
    }
    length--;
}

bool CircularLinkedList::Judge_HUIWEN() const {
    if (length == 0) return true;

    ListNode* front = head;
    ListNode* back = head;
    for (int i = 0; i < length; i++) {
        back = back->next;
    }
    
    for (int i = 0; i < length / 2; i++) {
        if (front->data != back->data) {
            return false;
        }
        front = front->next;
        back = head; // Reset back to head
        for (int j = 0; j < length - i - 1; j++) {
            back = back->next;
        }
    }
    return true;
}

int main() {
    CircularLinkedList obj;
    char temp[105] = {};
    cin >> temp;
    obj.CreateList(temp);
    if (obj.Judge_HUIWEN()) {
        obj.SequentialPrint();
        cout << "True" << endl;
    } else {
        obj.SequentialPrint();
        cout << "False" << endl;
    }
    
    while (true) {
        int x;
        cin >> x;
        obj.DeleteElement(x);
        obj.SequentialPrint();
    }
    return 0;
}

精彩评论(0)

0 0 举报