链表结构的定义与基本操作

89 阅读3分钟

Java版

import java.util.Stack;

class Node {
    int value;
    Node next;

    public Node(int value) {
        this.value = value;
    }
}

class MyLinkedList {

    // head节点是单链表的开始,不用来存储数据
    int size = 0;
    Node head = new Node(size);


    public Node getHead() {
        return head;
    }


    // 尾部插入结点
    public void add_Behind(Node node) {
        Node temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
        size++;
    }

    // 头部插入结点
    public void add_Front(Node node) {
        Node temp = head;
        if (temp.next != null) {
            node.next = temp.next;
        }
        temp.next = node;
        size++;
    }

    // 根据下标插入结点
    public boolean add_Index(int index, Node node) {
        if (index < 1 || index > size) {
            return false;
        }
        Node pre = head;
        int i = 1;
        while (pre.next != null) {
            if (i == index) {
                node.next = pre.next;
                pre.next = node;
                size++;
                return true;
            }
            pre = pre.next;
            i++;
        }
        return false;
    }


    // 删除尾部结点
    public boolean remove_Behind() {
        Node temp = head;
        if (temp.next == null) {
            return false;
        }
        while (temp.next.next != null) {
            temp = temp.next;
        }
        temp.next = null;
        size--;
        return true;
    }

    // 删除头部结点
    public boolean remove_Front() {
        Node temp = head;
        if (temp.next == null) {
            return false;
        }
        temp.next = temp.next.next;
        size--;
        return true;
    }

    // 根据下标删除结点
    public boolean remove_Index(int index) {
        if (index < 1 || index > size) {
            return false;
        }
        Node pre = head;
        int i = 1;
        while (pre.next != null) {
            if (i == index) {
                pre.next = pre.next.next;
                size--;
                return true;
            }
            pre = pre.next;
            i++;
        }
        return false;
    }


    public void print(Node temp) {
        while (temp != null) {
            System.out.println(temp.value);
            temp = temp.next;
        }
    }
}


public class B {

    public static void Creat(MyLinkedList link) {
        for (int i = 1; i <= 5; i++) {
            Node node = new Node(i);
            link.add_Behind(node);
        }
    }


    public static Node reverse(Node head) {
        Node prev = null;
        Node curr = head.next;   // 传入的是头结点,下面处理的时候要从首结点开始.。 如果传入的是首结点,直接写:Node curr = head
        head.next = null;     // 算法可以将存储数据的指针反转,但是头结点到首结点之间的指针没有处理,现在将他删去 。如果本身不带头结点,可以不写这一句
        while (curr != null) {
            Node next = curr.next;//记录保留当前结点的下一个结点的地址
            curr.next = prev;//当前结点指针域(原为下一个结点的地址)改为上一个节点的地址
            prev = curr;//上一个结点变为当前结点,为之后的循环做准备
            curr = next;//当前结点变为下一个结点,为之后的循环做准备
        }
        return prev;   // 返回的这个prev代表的结点,在物理上是最后一个,但是在逻辑上他是第一个存储数据的结点
    }

    public static void main(String[] args) {
        MyLinkedList link = new MyLinkedList();
        Node head = link.getHead();
        
        
        // 建立
        Creat(link);
        link.print(head.next);
        
        
        
        // 原地反转
        Node rev_head = reverse(head);
        link.print(rev_head);
    }
}



C++版

版本一(易理解)

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

typedef struct LinkList
{
    int data; 
    LinkList* next; //保存下一个结点的地址
}LinkList;

int n;//表长
LinkList L;//定义一个链表的头结点

//链表的初始化
void Init(LinkList* L)
{
    L->next = NULL;
}

//前插法创建
void Create_Q(LinkList* L)
{
    LinkList *p;
    cout<<"请输入表长:";
    cin>>n;
    cout<<"请依次输入链表结点值:";
    for (int i=0;i<n;i++)
    {
        p = (LinkList*)malloc(sizeof(LinkList));
        cin>>p->data;
        p->next=L->next;
        L->next=p;
    }
}

//后插法创建
void Create_H(LinkList* L)
{
    LinkList *p,*r;
    r=L;
    cout<<"请输入表长:";
    cin>>n;
    cout<<"请依次输入链表结点值:";
    for (int i=0;i<n;i++)
    {
        p = (LinkList*)malloc(sizeof(LinkList));
        cin>>p->data;
        p->next=NULL;
        r->next=p;
        r=p;
    }
}

//插入
int Insert(LinkList* L, int e, int index)
{
    if(index<1||index>n+1)
    {
        cout<<"位置错误";
        exit(0);
    }
    
    int i;
    LinkList *p, *s;

    //寻找前驱结点
    p = L; 
    for (i = 0; p&&(i < index-1); i++)
        p = p->next;
    
    
    if(!p||i>index-1)
        return 0;

    s = (LinkList*)malloc(sizeof(LinkList));
    s->data = e;

    s->next = p->next;
    p->next = s;

    n++;  //表长加1
    return 1;
}

//删除
int Delete(LinkList* L, int index)
{
    if(index<1||index>n)
    {
        cout<<"位置错误";
        exit(0);
    }
    int i;
    LinkList* p, *s;

    //寻找前驱结点
    p = L; 
    for (i = 0; i < index-1; i++)
        p = p->next;
    
    
    if(!p||i>index-1)
        return 0;
    s = p->next;
    int e = s->data;
    p->next = s->next;
    free(s);

    n--;  //表长减1
    return e;
}

//按位置查找
void IdSearch(LinkList * L, int index)
{
    if(index<1||index>n)
    {
        cout<<"位置错误";
        exit(0);
    }
    int i = 0;
    LinkList * p;
    p = L->next;
    while (i != index-1)
    {
        p = p->next;
        i++;
    }
    cout<<"序号为"<<index<<"的结点值:"<<p->data<<endl<<endl;

}

//按值查找
void ValueSearch(LinkList * L, int e)
{
    int i = 0;
    LinkList *p;
    p = L->next;
    while (p != NULL&&p->data != e)
    {
        p = p->next;
        i++;
    }
    if (p == NULL)
    {
       cout<<"该值不存在!"<<endl;
    }
    else if (p->data == e)
    {
        cout<<"结点值"<<e<<"的位置为:"<<i+1<<endl<<endl;
    }
}

//链表输出
void Print(LinkList* L)
{

    for (L = L->next; L != NULL; L = L->next)
        cout<<L->data<<"  ";
    cout<<endl<<endl;
}

int main()
{
    int Insert_Number,Insert_Location,Delete_Location,Seach_Id,Seach_Value;

    Init(&L);

    Create_H(&L);
    Print(&L);

    cout<<"请输入要插入的结点值及其位置:";
    cin>>Insert_Number>>Insert_Location;
    Insert(&L, Insert_Number, Insert_Location);
    Print(&L);

    cout<<"请输入要删除的结点的位置:";
    cin>>Delete_Location;
    int value =Delete(&L,Delete_Location);
    cout<<"删除的结点值为:"<<value<<endl<<endl;
    Print(&L);

    cout<<"请输入要查找的结点的序号:";
    cin>>Seach_Id;
    IdSearch(&L, Seach_Id);

    cout<<"请输入要查找的结点的值:";
    cin>>Seach_Value;
    ValueSearch(&L,Seach_Value);


    return 0;
}


版本二

#include<iostream>
#include<stdio.h>
#include<malloc.h>
using namespace std;


typedef struct LLinkList{
	int data;
	struct LLinkList *next;
}LLinkList,*LinkList;

int n;
//初始化(带头结点)
void Init1(LinkList &L)
{
	L=(LinkList)malloc(sizeof(LLinkList));
	L->next=NULL;
}

//初始化(不带头结点)
void Init2(LinkList &L) {
	L=NULL;
}

//前插法创建(带头结点)
void Create_Q(LinkList &L)
{
    LinkList p=L;
    cout<<"请输入表长:";
    cin>>n;
    cout<<"请依次输入链表结点值:";
    for (int i=1;i<=n;i++)
    {
        p = (LinkList)malloc(sizeof(LLinkList));
        cin>>p->data;
        p->next=L->next;
        L->next=p;
    }
}

//后插法创建(带头结点)
void Create_H(LinkList &L)
{
    LinkList p,r=L;
    cout<<"请输入表长:";
    cin>>n;
    cout<<"请依次输入链表结点值:";
    for (int i=1;i<=n;i++)
    {
        p = (LinkList)malloc(sizeof(LLinkList));
        cin>>p->data;
        p->next=NULL;
        r->next=p;
        r=p;
    }
}
//在第index个元素前插入新元素e(带头结点)
void Insert1(LinkList &L,int index,int e)
{
	int k;
	LinkList s,p=L;

	s=(LinkList)malloc(sizeof(LLinkList));
	s->data=e;
	for(k=1;k<index;k++)
        p=p->next;
	s->next=p->next;
	p->next=s;
}

//在第index个元素前插入新元素e(不带头结点)
void Insert2(LinkList &L,int index,int e)
{
	int k;
	LinkList s,p=L;

	s=(LinkList)malloc(sizeof(LLinkList));
	s->data=e;
	if(index==1)
	{
		s->next=L;
		L=s;
	}
	else
	{
		for(k=1;k<index-1;k++)
            p=p->next;
		s->next=p->next;
		p->next=s;
	}
}

//删除第index个元素,存入e中(带头结点)
void Delete1(LinkList &L,int index,int &e)
{
	int k;
	LinkList p=L,q;

	for(k=1;k<index;k++)
        p=p->next;
	q=p->next;
	e=q->data;
	p->next=q->next;
	free(q);
}
//删除第index个元素,存入e中(不带头结点)
void Delete2(LinkList &L,int index,int &e)
{
	int k;
	LinkList p=L,q;
	if(index==1)
	{
		q=L;
		e=q->data;
		L=L->next;
		free(q);
	}
	else
	{
		for(k=1;k<index-1;k++)
            p=p->next;
		q=p->next;
		e=q->data;
		p->next=q->next;
		free(q);
	}
}


//按值查找(带头结点)
int LocateElem(LinkList L,int e)
{
	int k=1;
	LinkList p=L->next;
	//LinkList p=L; 不带头结点的写法,函数中只有这一句不同
	while(p!=NULL)
	{
		if(p->data==e)
            return k;
		else
            k++;
		p=p->next;
	}
	return -1;//没找到
}





//销毁
void DestroyList(LinkList &L)
{
	LinkList p;
	while(L)
	{
		p=L->next;
		free(L);
		L=p;
	}
}

//清空
void ClearList(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
}

//判空
int LIstEmpty(LinkList L)
{
    //if(L=NULL)     (不带头结点的写法)
	if(L->next=NULL)
        return 1;
	else
        return 0;
}

//遍历
void Print(LinkList L)
{
	int k=0;
	LinkList p=L;
	while(p)
    {
        k++;
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
	//return k;  //返回元素个数
}

LinkList Merge(LinkList L1,LinkList L2)
{
    LinkList L= NULL;
    Print(L1);
     Print(L2);
     //Print(L);
	if(L1==NULL)    //这里不用带头节点的方法是因为递归Merge()参数中已经有一个next,这里如果用带头结点的,就要再加一个next,这样就会在一个链表为空时发生过度跳(跳两步)
		return L2;
	else if(L2==NULL)
		return L1;
		else{

		cout<<L1->data<<endl;
		cout<<L2->data<<endl;
	if(L1->data < L2->data)
	{
	    cout<<"L2大"<<endl;
		L=L1;
		L->next=Merge(L1->next,L2);
	}
	else
	{
	     cout<<"L1大"<<endl;
		L=L2;
		L->next=Merge(L1,L2->next);
	}
	return L;
		}



}


int main()
{
    //LinkList L;

   // Init1(L);
    //Create_H(L);

    LinkList L1,L2;
    Init1(L1);

Init1(L2);
Create_H(L1);
Create_H(L2);
//Print(L1);
    Print(Merge(L1->next,L2->next));
}


/***
4
1 3 5 7
4
2 4 6 8
***/