课件-链表用法-全
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
} return head ; }
建立链表过程
初始状态 读入1后
head NULL
head
tail NULL
temp NULL
tail temp
1 NULL
建立链表过程
读入2后 head
1
读入3后
hea d
1
tail tem p
2 NULL
tail
tem p
2
3
NULL
9.2.2 单向链表的操作
9.2.2 单向链表的操作
建立单向链表
声明一个链首指针变量head,并赋初值 NULL(包含0个节点的链表)
动态分配一个新节点,将该节点链入链尾 重复上一步
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
#include <iostream.h> struct node {
ቤተ መጻሕፍቲ ባይዱ
例子3:编写一个函数,在例1的链表 中查找包含指定整数的节点
node * findData(int n, node * head) {
node *curNode = head; while ( curNode ) {
if ( curNode->data == n) { cout<<"Find "<<n<<" in the list."<<endl; return curNode;
原链头节点的前驱指针指向新节点 新节点的后继指针指向原链头节点 新链头节点的前驱指针置为空指针
例子6:编写一个函数,按数据输入 的顺序建立双向链表
node *createBidirList (int n) { node *temp, *tail = NULL, *head = NULL ; int num; cin >> num; head = new node ; // 为新节点动态分配内存 if (head == NULL){ cout << "No memory available!"; return NULL; } else { head->data = num; head->next = NULL; head->pre = NULL; tail = head; }
双向链表的例子:
28
52
2
96
hea
d
NUL
L
NUL L
双向链表一般也由头指针唯一确定
双向链表首尾相接可以构成双向循环链 表
9.3.2 双向链表的操作
建立双向链表
新节点链入链尾
原链尾节点的后继指针指向新节点 新节点的前驱指针指向原链尾节点 新链尾节点的后继指针置为空指针
将新节点链入链头
课件-链表用法-全
讲授内容
自引用结构、链表的概念 内存的动态分配和释放 单向链表的定义与操作 双向链表的定义与操作
9.1 链表的基本概念
结构数组--必须将数组的大小设定成足 够大的值
太浪费 能否需要多少分配多少?
链表 = 动态内存分配 + 结构 + 指针
所有结构形成一条链 可以在任何地方插入或删除元素
9.2 单向链表
自引用结构
结构中包含指向同类型结构的指针 通过指针连接成链表,终点是NULL指针
(0)
9.2.1 单向链表定义
例子:
struct node { int data; node * next; };
next:指向下一个node类型的结构,连接node 的纽带
28
52
2
96
head
preNode = curNode; // 后节点变为前节点 curNode = curNode->next; } newNode = new node ; if (newNode == NULL) { cout << "No memory available!"; return head; }
例子4:编写一个函数,将输入的整 数从小到大插入链表
} return head ; }
9.3.2 双向链表的操作
双向链表的遍历
有链首节点,则可以沿着后继指针从 头至尾遍历
有链尾节点,则可以沿着前驱指针从 尾向头遍历
例子7:编写一个函数,输出双向链 表中各节点的data成员的值
void outputBidirList(node * head) { cout << "List: "; node *curNode = head; while ( curNode ) { if (curNode ->pre) cout << " <- "; cout << curNode->data; if (curNode ->next) cout << " -> "; curNode = curNode ->next; } cout << endl; return;
}
9.3 双向链表
单向链表:有利于从链首向链尾遍 历
有些时候双向遍历是需要的——双向 链表
9.3.1 双向链表的定义
定义双向链表的节点:
struct node {
int data; node * next; //指向后续节点 node * pre; //指向前面的节点 };
9.3.1 双向链表的定义
NULL
9.2.1 单向链表定义
存放学生信息的链表节点
struct student { int num; char name[20]; char sex; float score; student * next;
};
动态申请内存的方法
student *p=(student*) malloc(sizeof(student)); 或 student * p = new student;
例子6:编写一个函数,按数据输入 的顺序建立双向链表
for ( int i = 0; i < n - 1; i ++) { cin >> num; temp = new node ; // 为新节点动态分配内存 if (temp == NULL) { cout << "No memory available!"; return head; } else { temp->data = num; temp->next = NULL; temp->pre = tail; tail->next = temp; tail = temp; }
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
for ( int i = 0; i < n - 1; i ++) { cin >> num; temp = new node ; // 为新节点动态分配内存 if (temp == NULL) { cout << "No memory available!"; return head; } else { temp->data = num; temp->next = NULL; tail->next = temp; tail = temp; }
} curNode = curNode->next; } cout<<"Can't find "<<n<<" in the list."<<endl; return NULL; }
9.2.2 单向链表的操作
在链表中节点a之后插入节点c
(1) 指针cptr指向节点c,aptr指向节点a; (2) 把a后继节点的地址赋给节点c的后继指针
listHead = createList(n); return 0; }
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
node *createList(int n) { node *temp, *tail = NULL, *head = NULL ; int num; cin >> num; head = new node ; // 为新节点动态分配内存 if (head == NULL) { cout << "No memory available!"; return NULL; } else { head->data = num; head->next = NULL; tail = head; }
int data; node * next;
}; node * createList(int n); int main() {
int n; node * listHead = NULL; cout << "Please enter the number of nodes:"; cin >> n; if (n > 0)
包含指定整数的节点
node * deleteData(int n, node * head) { node *curNode = head;// 指向当前节点 node *preNode = NULL;// 指向当前节点的前驱节点 while (curNode && curNode->data != n) { preNode = curNode; // 当前节点变为前驱节点 curNode = curNode->next; } if (curNode == NULL) { cout<<"Can't find "<<n<<" in the list"<<endl; return head; } if (preNode == NULL) //删除链首节点 head = head->next; else preNode->next = curNode->next; delete curNode; return head; // 返回链首指针
遍历链表
依次访问链表中的每个节点的信息 head->data = 15; head->next->data = 15; 一般遍历方法
node * curNode = head; while (curNode )
curNode = curNode->next;
例子2:编写一个函数,输出例1链表 中各节点的data成员的值
void outputList(node * head) {
cout << "List: "; node *curNode = head; while ( curNode ) {
cout << curNode->data; if (curNode ->next)
cout << " -> "; curNode = curNode ->next; } cout << endl; return; }
newNode->data = n; if (preNode == NULL) //插入到链表头 {
newNode->next = curNode; return newNode; } else { preNode->next = newNode; newNode->next = curNode; return head; } }
cptr->next=aptr->next; (3) 把c的地址赋给节点a的后继指针
aptr->next=cptr;
例子4:编写一个函数,将输入的整 数从小到大插入链表
node * insertData(int n, node * head) {
node *curNode = head;// 指向插入点的后节点 node *preNode = NULL;// 指向插入点的前节点 node *newNode = NULL;// 指向新建节点 while ((curNode!=NULL)&&(curNode->data<n)) {
}
9.3.2 双向链表的操作
在双向链表中插入和删除一个节点
优点:获取插入节点或被删除节点的前驱和 后继节点比较方便
注意点:需要维护的指针较多
例子8:编写函数,将整数n插入到一 个已排序的双向链表中(从小到大)
node * insertData(int n, node * head) { node *curNode = head; // 指向插入点的后节点 node *preNode = NULL; // 指向插入点的前节点 node *newNode = NULL; // 指向新建节点 //寻找插入位置 while((curNode != NULL)&&(curNode->data < n)) { preNode = curNode; curNode = curNode->next;
9.2.2 单向链表的操作
从链表中删除一个节点c
(1)在链表中查找要删除的节点c,用指针cptr 指向节点c;
(2)如果c有前驱节点(设为d,用指针dptr指向 d),则将d的后继指针指向c的后继节点: dptr->next=cptr->next
(3)释放c占用的空间
例子5:编写一个函数,删除链表中
建立链表过程
初始状态 读入1后
head NULL
head
tail NULL
temp NULL
tail temp
1 NULL
建立链表过程
读入2后 head
1
读入3后
hea d
1
tail tem p
2 NULL
tail
tem p
2
3
NULL
9.2.2 单向链表的操作
9.2.2 单向链表的操作
建立单向链表
声明一个链首指针变量head,并赋初值 NULL(包含0个节点的链表)
动态分配一个新节点,将该节点链入链尾 重复上一步
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
#include <iostream.h> struct node {
ቤተ መጻሕፍቲ ባይዱ
例子3:编写一个函数,在例1的链表 中查找包含指定整数的节点
node * findData(int n, node * head) {
node *curNode = head; while ( curNode ) {
if ( curNode->data == n) { cout<<"Find "<<n<<" in the list."<<endl; return curNode;
原链头节点的前驱指针指向新节点 新节点的后继指针指向原链头节点 新链头节点的前驱指针置为空指针
例子6:编写一个函数,按数据输入 的顺序建立双向链表
node *createBidirList (int n) { node *temp, *tail = NULL, *head = NULL ; int num; cin >> num; head = new node ; // 为新节点动态分配内存 if (head == NULL){ cout << "No memory available!"; return NULL; } else { head->data = num; head->next = NULL; head->pre = NULL; tail = head; }
双向链表的例子:
28
52
2
96
hea
d
NUL
L
NUL L
双向链表一般也由头指针唯一确定
双向链表首尾相接可以构成双向循环链 表
9.3.2 双向链表的操作
建立双向链表
新节点链入链尾
原链尾节点的后继指针指向新节点 新节点的前驱指针指向原链尾节点 新链尾节点的后继指针置为空指针
将新节点链入链头
课件-链表用法-全
讲授内容
自引用结构、链表的概念 内存的动态分配和释放 单向链表的定义与操作 双向链表的定义与操作
9.1 链表的基本概念
结构数组--必须将数组的大小设定成足 够大的值
太浪费 能否需要多少分配多少?
链表 = 动态内存分配 + 结构 + 指针
所有结构形成一条链 可以在任何地方插入或删除元素
9.2 单向链表
自引用结构
结构中包含指向同类型结构的指针 通过指针连接成链表,终点是NULL指针
(0)
9.2.1 单向链表定义
例子:
struct node { int data; node * next; };
next:指向下一个node类型的结构,连接node 的纽带
28
52
2
96
head
preNode = curNode; // 后节点变为前节点 curNode = curNode->next; } newNode = new node ; if (newNode == NULL) { cout << "No memory available!"; return head; }
例子4:编写一个函数,将输入的整 数从小到大插入链表
} return head ; }
9.3.2 双向链表的操作
双向链表的遍历
有链首节点,则可以沿着后继指针从 头至尾遍历
有链尾节点,则可以沿着前驱指针从 尾向头遍历
例子7:编写一个函数,输出双向链 表中各节点的data成员的值
void outputBidirList(node * head) { cout << "List: "; node *curNode = head; while ( curNode ) { if (curNode ->pre) cout << " <- "; cout << curNode->data; if (curNode ->next) cout << " -> "; curNode = curNode ->next; } cout << endl; return;
}
9.3 双向链表
单向链表:有利于从链首向链尾遍 历
有些时候双向遍历是需要的——双向 链表
9.3.1 双向链表的定义
定义双向链表的节点:
struct node {
int data; node * next; //指向后续节点 node * pre; //指向前面的节点 };
9.3.1 双向链表的定义
NULL
9.2.1 单向链表定义
存放学生信息的链表节点
struct student { int num; char name[20]; char sex; float score; student * next;
};
动态申请内存的方法
student *p=(student*) malloc(sizeof(student)); 或 student * p = new student;
例子6:编写一个函数,按数据输入 的顺序建立双向链表
for ( int i = 0; i < n - 1; i ++) { cin >> num; temp = new node ; // 为新节点动态分配内存 if (temp == NULL) { cout << "No memory available!"; return head; } else { temp->data = num; temp->next = NULL; temp->pre = tail; tail->next = temp; tail = temp; }
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
for ( int i = 0; i < n - 1; i ++) { cin >> num; temp = new node ; // 为新节点动态分配内存 if (temp == NULL) { cout << "No memory available!"; return head; } else { temp->data = num; temp->next = NULL; tail->next = temp; tail = temp; }
} curNode = curNode->next; } cout<<"Can't find "<<n<<" in the list."<<endl; return NULL; }
9.2.2 单向链表的操作
在链表中节点a之后插入节点c
(1) 指针cptr指向节点c,aptr指向节点a; (2) 把a后继节点的地址赋给节点c的后继指针
listHead = createList(n); return 0; }
例子1:建立链表,读入n个整数,每 个整数作为一个新结点插入到链尾
node *createList(int n) { node *temp, *tail = NULL, *head = NULL ; int num; cin >> num; head = new node ; // 为新节点动态分配内存 if (head == NULL) { cout << "No memory available!"; return NULL; } else { head->data = num; head->next = NULL; tail = head; }
int data; node * next;
}; node * createList(int n); int main() {
int n; node * listHead = NULL; cout << "Please enter the number of nodes:"; cin >> n; if (n > 0)
包含指定整数的节点
node * deleteData(int n, node * head) { node *curNode = head;// 指向当前节点 node *preNode = NULL;// 指向当前节点的前驱节点 while (curNode && curNode->data != n) { preNode = curNode; // 当前节点变为前驱节点 curNode = curNode->next; } if (curNode == NULL) { cout<<"Can't find "<<n<<" in the list"<<endl; return head; } if (preNode == NULL) //删除链首节点 head = head->next; else preNode->next = curNode->next; delete curNode; return head; // 返回链首指针
遍历链表
依次访问链表中的每个节点的信息 head->data = 15; head->next->data = 15; 一般遍历方法
node * curNode = head; while (curNode )
curNode = curNode->next;
例子2:编写一个函数,输出例1链表 中各节点的data成员的值
void outputList(node * head) {
cout << "List: "; node *curNode = head; while ( curNode ) {
cout << curNode->data; if (curNode ->next)
cout << " -> "; curNode = curNode ->next; } cout << endl; return; }
newNode->data = n; if (preNode == NULL) //插入到链表头 {
newNode->next = curNode; return newNode; } else { preNode->next = newNode; newNode->next = curNode; return head; } }
cptr->next=aptr->next; (3) 把c的地址赋给节点a的后继指针
aptr->next=cptr;
例子4:编写一个函数,将输入的整 数从小到大插入链表
node * insertData(int n, node * head) {
node *curNode = head;// 指向插入点的后节点 node *preNode = NULL;// 指向插入点的前节点 node *newNode = NULL;// 指向新建节点 while ((curNode!=NULL)&&(curNode->data<n)) {
}
9.3.2 双向链表的操作
在双向链表中插入和删除一个节点
优点:获取插入节点或被删除节点的前驱和 后继节点比较方便
注意点:需要维护的指针较多
例子8:编写函数,将整数n插入到一 个已排序的双向链表中(从小到大)
node * insertData(int n, node * head) { node *curNode = head; // 指向插入点的后节点 node *preNode = NULL; // 指向插入点的前节点 node *newNode = NULL; // 指向新建节点 //寻找插入位置 while((curNode != NULL)&&(curNode->data < n)) { preNode = curNode; curNode = curNode->next;
9.2.2 单向链表的操作
从链表中删除一个节点c
(1)在链表中查找要删除的节点c,用指针cptr 指向节点c;
(2)如果c有前驱节点(设为d,用指针dptr指向 d),则将d的后继指针指向c的后继节点: dptr->next=cptr->next
(3)释放c占用的空间
例子5:编写一个函数,删除链表中