学习数据结构——线性表与链表
来源:互联网 发布:淘宝魔切页面 编辑:程序博客网 时间:2024/06/05 13:28
线性表是一种最基本的数据结构,通常可以分为顺序表和链表。
顺序表即数据的存储空间是连续的,而链表的前后元素需要靠指针来连接。
顺序表简单,但是通常存在着
- 插入删除操作时需要移动大量数据,效率极低;
- 最大表长度难以估计,太大了浪费空间,太小了容易溢出。
但是链表的性质却可以很好的解决以上两个问题。以下是两个链表的示例程序。一个静态,一个动态,均有较详细的注释,以备日后回顾复习。
注意,在Visual Studio的高版本(一般高于VS2013)中运行两个程序时,`scanf()`函数会报错,或者出现这样的问题:error C4703: 使用了可能未初始化的本地指针变量“xxx”这时可以打开 项目属性->配置属性->C/C++->SDL检查,选择SDL检查为“否”,即可解决问题。
静态链表示例程序
用数组模拟静态的链表,长度预先定义好,不能动态分配内存。
//简单静态链表#include <iostream>using namespace std;struct student{ long num; float score; struct student * next; //指向该类结构体}; //注意分号int main(){ struct student a,b,c,* head,* p; a.num = 0001; a.score = 99; b.num = 0002; b.score = 98; c.num = 0003; c.score = 97; head = &a; //头指针 a.next = &b; b.next = &c; c.next = NULL; //尾指针 p = head; //迭代的时候不能用头指针本身去迭代,否则就乱了 do { cout << p->num << " " << p->score << endl; p = p->next; }while( p != NULL ); getchar(); //输出结果后起到暂停作用 }
动态链表示例程序,包含链表常用的若干种操作
用指针实现动态链表,malloc函数和free函数可以实现内存的动态分配。具有较大灵活性。
注意在C++语言中使用printf()
函数要引入标准输入输出库。C语言中使用#include <stdio.h>
,而C++语言中使用#include <cstdio>
来实现。
//动态链表程序#include "stdafx.h"#include <cstdio>#include <iostream>#include <cstdlib>using namespace std;using namespace std;typedef int ElemType;typedef struct List * link;typedef struct List Lnode;struct List //定义链表{ ElemType data; struct List * next;};link setnull(link Head) //置空链表,输入一个链表的头指针{ link p; p = Head; //头指针赋给指针p while (p != NULL) { p = p->next; //p指向链表的下一个元素 free(Head); //把p指针的上一个指针(Head)所占空间释放 Head = p; //p所指的结点(node)成为新的Head } return Head;}link insert(link Head, ElemType x, int i) // Head是已知链表,x是要插入的数,i是插入位置{ link NewPoint, p = Head; int j = 1; NewPoint = (link)malloc(sizeof(Lnode)); //生成一个link类型的,长度为一个节点的内存空间 NewPoint->data = x; if (i == 1) //如果插入位置是第一个,直接令NewPoint为头指针,NewPoint的next指向原第一个结点 { NewPoint->next = Head; Head = NewPoint; } else { while (j<i - 1 && p->next != NULL) //把p指针从头移到要插入的前一位 { p = p->next; j++; //此时j应该等于i-1 } if (j == i - 1) //把NewPoint插进去 { NewPoint->next = p->next; p->next = NewPoint; } else //超过范围就报错 { printf("insert is failure,i is not right!"); } } return Head; //最后返回更改后的链表指针}link create(link Head) //生成链表{ ElemType newData; //新数据 link NewPoint; //新指针 Head = (link)malloc(sizeof(Lnode)); //给头指针分配一个节点大小的内存空间 printf("please input number: \n"); printf("caution! 倒序输入 \n"); scanf("%d", &newData); printf("you type %d as the last number\n", newData); //cin >> newData; Head->data = newData; Head->next = NULL; //头指针的后面暂无结点 while (1) { NewPoint = (link)malloc(sizeof(Lnode)); //产生新节点 if (NewPoint == NULL) //如果分配内存失败,跳出while { break; } printf("please input number : input '-1' means exit\n"); scanf("%d", &newData); //cin >> newData; if (newData == -1) //结束标志 { return Head; } NewPoint->data = newData; //把NewPoint接在Head前面 NewPoint->next = Head; Head = NewPoint; } return Head;}int length(link Head) // 计算一个链表的长度{ int len = 0; link p; //不要直接操作Head,会改乱指针 p = Head; while (p != NULL) //只要p不是空指针,就计数 { len++; p = p->next; } return len;}ElemType get(link Head, int i) // 返回Head链表的i位置的数据{ int j = 1; link p; p = Head; while (j<i && p != NULL) { p = p->next; j++; } if (p != NULL) { return (p->data); } else//这种情况出现在给定的i超过了链表的长度 { //printf("data is error!"); cout << "data is error!"; } return -1;}int locate(link Head, ElemType x) //在给定链表中确定数据x的位置{ int n = 0; link p; p = Head; while (p != NULL && p->data != x) //一直找,找到x前一个停下 { p = p->next; n++; } if (p == NULL) //如果Head链表里没有这个数据,p会最终指到NULL上 { return -1; } else { return n + 1; }}void display(link Head) //在屏幕上打印链表{ link p; p = Head; if (p == NULL) { //printf("\nList is empty"); cout << "\nList is empty"; } else { do { printf("%d", p->data); p = p->next; } while (p != NULL); } cout << endl;}link connect(link Head1, link Head2) //将两个链表连接起来,Head1在前,Head2在后{ link p; p = Head1; while (p->next != NULL) //p指针一直指到Head1链表的最后一个结点处 { p = p->next; } p->next = Head2; //在Head1最后接上Head2链表的第一个结点 return Head1;}link del(link Head, int i) //删除{ int j = 1; link p, t; p = Head; if (i == 1) { p = p->next; //如果要删除的是第一个位置的数据,就把p指针指向下一个元素,然后将Head释放 free(Head); //释放p所指的空间 Head = p; //新的头指针 } else //如果要删除的元素不在第一个位置 { while (j < i - 1 && p->next != NULL) //先将p指向要删除的结点的前一个位置,而且要保证要删除的元素没有超出链表的长度 { p = p->next; j++; } if (p->next != NULL && j == i - 1) { t = p->next; p->next = t->next; //直接跳过第i个结点,将第i-1个结点和第i+1个结点连在一起 } if (t != NULL) { free(t); //把中间变量释放掉 } } return Head;}int compare(link Head1, link Head2) //比较两个链表是否相同:长度一致,且数据相同{ link p1, p2; p1 = Head1; p2 = Head2; while (1) { if ((p1->next == NULL) && (p2->next == NULL)) //当Head1和Head2同时达到链尾才成立 { return 1; //两链表相同 } if (p1->data != p2->data) //比较过程中只要有不一样的数据就返回0 { return 0; } else { p1 = p1->next; //不断迭代 p2 = p2->next; } }}int main(){ int l; link head1 = NULL; link head2 = NULL; printf("\nNow we generate the first linked list\n"); head1 = create(head1); //生成第一个链表 printf("\nHead1 is :\n"); //显示出来 display(head1); printf("\nNow we generate the second linked list\n"); head2 = create(head2); //生成第二个链表 printf("\nHead2 is :\n"); //显示出来 display(head2); printf("\nNow we compare the two linked lists\n"); //比较两个链表是否相同 l = compare(head1, head2); printf("\nl is %d\n", l); printf("\nNow we connect two linked lists\n"); connect(head1, head2); //将head1与head2接起来 printf("\nHead1 + Head2 is \n"); display(head1); printf("\nNow we calculate the first linked list\n"); l = length(head1); //计算head1的长度 printf("\nthe length of link1 is %d\n", l); l = get(head1, 3); //获取head1链表第三个元素的值 printf("\nthe 3th element of link1 is %d\n", l); l = locate(head1, 12); //查找12在链表中的位置,没有则返回1 printf("\nlocate 12 is %d \n", l); printf("\nNow we insert 555 to 8th of the first linked list\n"); head1 = insert(head1, 555, 8); //在第8位插入数据555 display(head1); printf("\nNow we delete the 7th element of the first linked list\n"); head1 = del(head1, 7); //删除第7个结点 display(head1); printf("\nNow we clear the first linked list\n"); head1 = setnull(head1); //将head1置空 display(head1); printf("\nNow wait to exit: press any key and enter\n"); cin >> l; return 0;}
阅读全文
0 0
- 学习数据结构——线性表与链表
- 数据结构与算法学习笔记——线性表
- 数据结构学习——线性表
- 数据结构学习——线性表
- 数据结构——线性表的学习
- 数据结构学习笔记——线性表
- 数据结构学习笔记——线性表
- 数据结构学习——线性表
- 数据结构与算法学习03-线性表
- 数据结构—线性表
- 数据结构—线性表
- 数据结构—线性表
- 数据结构—线性表
- 数据结构——线性表之链表存储学习
- 数据结构学习---线性表
- 数据结构学习-线性表
- 【数据结构学习】线性表
- [数据结构]线性结构——线性表
- Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述
- ajax请求
- JVM-运行时数据区域(2)
- 8、9、10月读书
- flume properties配置文件详解
- 学习数据结构——线性表与链表
- Eclipse快捷键(常用)
- HDU
- 第2章-从头开始:自然数 2.1-Peano 公理
- git常用命令学习笔记
- Kubernetes常用命令(kubectl)
- 九鼎之尊(一)(二)
- IDEA下maven工程的classpath
- EL JSTL