数据结构与算法设计-----单链表操作

实验目的:
1、掌握线性表的链式存储结构的表示与实现。
2、掌握和验证单链表上各类操作的实现方法。
3、掌握C++编程中的一些基本编程规范。
实验要求:
实现单链表的基本操作
1)构造空的单链表;
2)建立含有若干数据元素的单链表并输出;
3)求表长;
4)获取第三个元素的值;
5)在第四个位置后,插入一个值为“38”的新的元素后输出单链表;
6)删除第五个位置上的元素后输出单链表;

测试数据:23 33 21 45 67 98

下面就以本次实验来讲解单链表操作的实现:

一、首先需要自定义一个结点类型的结构体:

struct LNode{
    int data;	//数据域
    struct LNode* next;		//指针域
}LNode, *LinkList;

二、实现单链表的创建,并且初始化,这里使用的是尾插法:

void Init(struct LNode* L) { //创建并且初始化链表
    int cur;
	cout<<"请输入数据并且以-1结束:";
    cin >> cur;
    while (cur != -1) {
		struct LNode* ptr = (struct LNode*)malloc(sizeof(struct LNode));	 //使用malloc()函数为ptr申请空间
        ptr->data= cur;
        ptr->next = NULL;
        L->next = ptr;
        L = L->next;
        cin >> cur;
    }
}

三、实现链表的遍历

void Show(struct LNode* L) { //遍历链表值
    cout << "链表遍历:" ;
    
    while (L->next) {
        cout << L->next->data << " ";
        L = L->next;
    }
    cout << endl;
}

四、求链表的长度

int lengthList (struct LNode* L) {   //求链表长度
    int len = 0;
    while (L->next) { 
        len ++;
        L = L->next;
    }
    return len;
}

或者这里也可以是一个没有返回类型的函数,代码如下:

void lengthList (struct LNode* L) {   //求链表长度
    int len = 0;
    while (L->next) { 
        len ++;
        L = L->next;
    }
    cout<<"链表的长度为:"<<len;
}

五、实现数据的插入,在第k个位置插入数据,数据值为n

void InsertList (struct LNode* L, int k, int n) {
    
    struct LNode* pre = NULL; //存储第K-1个元素的值
    struct LNode* ptr = (struct LNode*)malloc(sizeof(struct LNode));   //申请空间
    ptr->data = n;
    ptr->next = NULL;
    
    while (k && L->next) {  //查找到放置data元素的位置
        pre = L;
        L = L->next;
        k --;
    }
    
    if (k > 0) {    //如果K > 0 直接插到链表的表尾
        L->next = ptr;
        L = L->next;
    }else {
        pre->next = ptr;    //链接链表
        ptr->next = L;
    }
}

六、实现数据的删除,数据的删除有两种实现方法
(一)是按照位置删除数据,删除第k个位置的元素

void DeleteList_Position(struct LNode* L, int k) {   //删除第K个位置的结点
    if (lengthList(L) <= 0) {
        cout << "表空,没有元素可删除" << endl;
        return;
    }
 
    struct LNode* ptr = L->next;
    struct LNode* pre = L;   //记录ptr的前一个位置的结点
    k = k - 1;  //因为如果k = 1,直接用pre->next = ptr->next就把ptr删掉了,所以要减1
    while (k-- && ptr) {
        pre = ptr;
        ptr = ptr->next;
    } 
    if (ptr == NULL || k > 0) {
        cout << "要删除的位置不存在" << endl;
    }else {
        pre->next = ptr->next;  //删除ptr结点
        free(ptr);  //释放空间
    }
}

(二)是按照值来删除数据,删除值为x的元素

void DeleteList (struct LNode* L, int x) {   //删除值为x的结点(链表无重复值)
    if (lengthList(L) <= 0) {
        cout << "表空,没有元素可删除" << endl;
        return;
    }
 
    struct LNode* ptr = L->next;
    struct LNode* pre = L;   //记录ptr的前一个位置的结点
    while (ptr) {
        if (ptr->data == x) {
            pre->next = ptr->next;  //把x值的结点的前一个结点的next指向ptr的next结点
            free(ptr);  //释放空间
            return;
        }
        pre = ptr;
        ptr = pre->next;
    }
}

有没有小伙伴发现这段代码有一个缺陷,就是如果按照值删除的话,链表中的元素是不能够有重复的元素的,如果有重复的元素,就默认删除第一个出现该值得元素。

七、获取链表中某个元素的值

int GetElemList(struct LNode* L, int i) {    //返回第i个位置的值
    struct LNode* ptr = L;
    int k = i;  //标记i的值,以防不存在输出显示
    while (i > 0 && ptr->next) {
        ptr = ptr->next;
        i --;
    }
 
    if (i == 0 && ptr != NULL) {    //当i == 0 和 ptr 不为空代表找到了第i个位置的元素
        return ptr->data;
    }else {
        cout << "第" << k << "个位置不存在" << endl;
        return -1;
    }
}

上面代码就是实现了链表操作的各种功能,下面是主函数:

/*实现单链表的基本操作
1)构造空的单链表;
2)建立含有若干数据元素的单链表并输出;
3)求表长;
4)获取第三个元素的值;
5)在第四个位置后,插入一个值为“38”的新的元素后输出单链表;
6)删除第五个位置上的元素后输出单链表;*/


void main() {
    struct LNode* head = (struct LNode*)malloc(sizeof(struct LNode));  //头结点(不存值)
    head->next = NULL;  
    cout<<"表长为:"<<lengthList(head)<<endl;//求表长;
	GetElemList(head, 3);//获取第三个元素的值
	Show(head);//后输出单链表
	InsertList(head, 5, 38);//在第四个位置后,插入一个值为“38”的新的元素
	Show(head);//输出单链表
	DeleteList_Position(head, 5);//删除第五个位置上的元素
	Show(head);//输出单链表
}

以上就是单链表的算法实现,单链表的实现方式十分灵活,有多种实现方法,但是在数据结构上都十分相似。上述代码仅是个人学习中的总结,如有不足之处,请指正批评~~

你可能感兴趣的:(链表,算法,c++,数据结构)