数据结构oj_10

移除序列指定位置元素(链表)

问题描述 :

使用带头结点的单链表编程:

一群学生排成一行,输入一个位置,将该位置的学生移除。

第一个学生的位置为1,第n个学生的位置为n。

输入说明 :

第一行输入学生信息:

第一个整数n(0<=n<=100),表示共有n个学生,其后有n个整数,表示n个学生的学号

第二行及以后各行,每行输入一个整数,表示要移除的学生位置。

输出说明 :

每次移除一个学生后,在一行里输出完整的学号序列,以head开头,以tail结尾,学号之间以“–>”分隔(参见范例)。

如果需要移除学生的位置不合法,则输出“invalid”(不包括双引号)

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
using namespace std;
struct student {<!-- -->
    int num;
    struct student* next;
};
student* creat(student *head, int n) {<!-- -->
//  cout << "创建链表" << endl;
    student *p, *q;
    p = head;
    q = head;
    for (int j = 1; j <= n; j++) {<!-- -->
        q = new student;
        p->next = q;
        p = q;
        cin >> p->num;
    }
    q->next = NULL;
    return head;
}
student* input(student* head, int n, int m) {<!-- -->
    head->num = 1;//num置1表状态正常,置0后返回invalid
    student *p, *q;
    student* mid = new student;
    mid->num = n;
    p = head;
    q = p;
    if (m == 1) {<!-- -->
        //段首插入mid
        if (head->next) {<!-- -->
            mid->next = head->next;
            head->next = mid;
        }
        else {<!-- -->
            //仅有头节点
            head->next = mid;
            mid->next = NULL;
        }
        return head;
    }
    else {<!-- -->
        for (int i = 1; i < m; i++) {<!-- -->
            //插入段向后移动并判断是否为段尾
            q = p;
            if (p->next == NULL) {<!-- -->
                head->num = 0;
                //仅有头节点且不在首位插入num置0
                return head;
            }
            p = p->next;
            if (p->next == NULL) {<!-- -->
                if (i < m - 1) {<!-- -->
                    //在段尾且还需移动num置0
                    head->num = 0;
                    return head;
                }
                else {<!-- -->
                    p->next = mid;
                    mid->next = NULL;
                    return head;
                }
            }
        }
        //中间插入mid
        p = p->next;
        q = q->next;
        mid->next = q->next;
        q->next = mid;
        return head;
    }
}

student* del(student* head, int n) {<!-- -->
//  cout << "删除节点" << endl;
    head->num = 1;
    student *p, *q;
    p = head;
    q = head;
    for (int i = 0; i < n; i++) {<!-- -->
        q = p;
        p = p->next;
        if (q->next == NULL) {<!-- -->
            head->num = 0;
            return head;
        }
        if (p->next == NULL) {<!-- -->
            if (i < n - 1) {<!-- -->
                head->num = 0;
                return head;
            }
            else {<!-- -->
                q->next = NULL;
                delete p;
                return head;
            }
        }
    }
    q->next = p->next;
    delete p;
    return head;
}


//head中值作为链表状态表示,实际使用中不对head做实际操作与显示
int main() {<!-- -->
    student* head = new student;
    int m,n, i;
    cin >> i;
    if (i == 0) {<!-- -->
        head->next = NULL;
    }
    else {<!-- -->
        head = creat(head, i);
    }
    while (cin >> m ) {<!-- -->
        if (m <= 0) {<!-- -->
            cout << "invalid" << endl;
        }
        else {<!-- -->
            head = del(head, m);
//          head = input(head, n, m);
            if (head->num != 0) {<!-- -->//判断num读数
                cout << "head-->";
                student *p = head;
                while (p->next != NULL) {<!-- -->
                    p = p->next;
                    cout << p->num << "-->";
                }
                cout << "tail" << endl;
            }
            else {<!-- -->
                cout << "invalid" << endl;
            }
        }
    }
    return 0;
}

因为今天已经到了发布文章限制(10篇),剩下的明天再发吧